Passing a _ConnectionPtr from C++ to C#

Posted on 2009-04-17
Last Modified: 2012-05-06
I am developing a C# project that must interact with some legacy C++ code. I do not have control over any part of the C++ code, other than creating the link to my C# code.

Both the C++ code and the C# code must access a Sysbase databse using an ODBC connection. The C++ code opens a connection to a Sybase database using ADO. The connection is then stored in a _ConnectionPtr smart pointer. The C++ code eventually must call my C# code, which is compiled in a separate dll. My C# code also needs to access this same database.

I know how to create a connection string and open an ODBC connection in C#, but I have been instructed to avoid opening a separate connection to the database if at all possible. So what I need to do is have my C# code use the same connection that was opened by the C++ code. How can I pass the connection from the C++ code to the C# code or have the C# code reach back into the C++ code and access the connection? I've been researching options using COM and Marshalling, but I haven't really gotten anywhere. Is it possible for the C++ and C# code to use the same connection? If so how can the connection be communicated from one dll to the other.

Thanks for the help and let me know if any further details would be useful.
Question by:qadmin
    LVL 10

    Expert Comment

    Hi, is the pointer propagated (accessible) to your C# code somehow (IntPtr) ?

    LVL 39

    Expert Comment

    If you cannot change the C++ code and if there's no interface to the connection, i.e., if you only have the connection pointer, the two things that you can do are (imo):

    1. create a wrapper in C++ that acts on the connection pointer. This wrapper then exposes a COM interface which you can access from C#, or you expose a DLL interface, which you can also access from C#. The problem is, however, that you need to do a lot of marshalling, and re-coding to get this done.

    2. create a new connection. Even if they say that many connections is not a good thing, I'm sure it is better than spending several days or weeks developing a connection wrapper.

    Alternatively (yes, there's a 3), complex applications that need much control over their database connectivity should have a middle tier layer that serves as DAL, which can take care as connection manager and ORM and DAL at the same time. There are many ORM + DALs available, but I'm not sure you would want to go down that path.

    Btw: can you tell us the type of the object that uses the connection pointer and the declaration of the method that can be used to retrieve that pointer? I assume it is already some kind of library with dll_export functions?

    -- Abel --
    LVL 86

    Assisted Solution

    >>create a wrapper in C++ that acts on the connection pointer. This wrapper
    >>then exposes a COM interface which you can access from C#

    Or, maybe better: Since an ADO connection is a COM interface itself, why not accessing it directly via COM Interop?

    Author Comment

    Thanks for presenting those options. I completely agree with you that the simple and easy solution of opening a separate connection is attractive, we'll have to do a cost/benefit analysis once I get some information.

    To answer your question, the C++ code has a Connection manager object (let's just call it Manager) that is responsible for creating the connection pointer. When the program first starts up, the user is prompted for a user name and password, the Manager opens the connection and creates the pointer, from that point on the rest of the code accesses the pointer via an attribute of the Manager class. The method used to retrieve the pointer is in the windows file "msado15.dll", which itself uses COM. So the code to declare, create, and open the connection looks like this:

    _ConnectionPtr pConnection;
    pConnection->Open(...connection string and some other parameters ...);

    I haven't really worked with COM before, and I'm new to using ADO in C++ so I admit that I'm not totally sure what's going on here, but that is the code.

    I'm still not clear on something. let's say I take option 1. and create a wrapper in C++. My C# code accesses the COM interface of this wrapper to get at the connection pointer. What does my C# code do with the pointer once it gets it? The C# code really wants an OdbcConnection object, not a _ConnectionPtr. Thanks again.
    LVL 86

    Expert Comment

    Well, let's start like that: How does the C++ code expose the _ConnectionPtr at the moment?
    LVL 39

    Accepted Solution

    > The C# code really wants an OdbcConnection object, not a _ConnectionPtr.

    my idea with nr 1 was to let all the work be done in the wrapper (passing it on to the C++ object). That would be a "fat wrapper", because it would need to mimic some of the ODBC connection semantics which would currently not be available in the current COM interface. The reason for choosing C++ is that you can use the same of dealing with that pointer.Now that we found out that you already have a COM interface, that might not be needed.

    But like jkr is asking, how is the pointer exposed? And are there other methods exposed that you can use?

    Author Comment

    Thanks to all the experts for your help so far. I'm trying out a few options based on your suggestions. I should have some more information in a few days.

    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Join & Write a Comment

    Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
    Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
    The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
    The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

    755 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    24 Experts available now in Live!

    Get 1:1 Help Now