• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 812
  • Last Modified:

Passing a _ConnectionPtr from C++ to C#

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.
0
qadmin
Asked:
qadmin
  • 2
  • 2
  • 2
  • +1
2 Solutions
 
_Katka_Commented:
Hi, is the pointer propagated (accessible) to your C# code somehow (IntPtr) ?

regards,
Kate
0
 
abelCommented:
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 --
0
 
jkrCommented:
>>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?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
qadminAuthor Commented:
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.Connection.CreateInstance(_uuidof(Connection));
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.
0
 
jkrCommented:
Well, let's start like that: How does the C++ code expose the _ConnectionPtr at the moment?
0
 
abelCommented:
> 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?
0
 
qadminAuthor Commented:
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.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 2
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now