1. problem with calling C++/CLI wrapper to C++ code from C# appli
It occured to be my error unrelated to anything written in the post. If directories are properly assigned everything works fine. -- phys
2. problem with calling C++/CLI wrapper to C++ code from C# applicati
3. Wrapper Component in C++/CLI to use Legacy C++ code/functionality in C#
Hi,
We have legacy code in C/C++, I am writing a wrapper component in C++/
CLI that will allow using this legacy code functionality in C#, I have
linked all my static libraries to this C++/CLI DLL project
I have created a wrapper public static ref class in C++/CLI project
that will expose functions for the C# client.
Problem:
when I use a function that returns a pointer or that has pointer
arguments, in the C++/CLI project, The C# client where this wrapper
component is referenced, gives a runtime error when i try to access
the wrapper function,
Error:
"The handle is invalid. (Exception from HRESULT: 0x80070006
(E_HANDLE))"
How do I use functions that accept/return pointer arguments in my C++/
CLI component so that I can use the functionality in C#??
C++/CLI code
#pragma managed
public ref class LibFunctions
{
public:
static String^ GetDefaultMgr(void)
{
get_default_manager(); //this is a c function that returns
a TCHAR*
}
};
C# client code:
private void DefMgr_Click(object sender, EventArgs e)
{
try
{
MessageBox.Show(LibFunctions.GetDefaultMgr());
}
catch (Exception exception)
{
MessageBox.Show(exception.Message);
}
}
5. C++ dll1 calls c#-wrapper-dll calls C++ dll2
Hi,
I have the following situation:
I have one C++-dll that I am not allowed to touch (dll1)
dll1 calls a C++ dll2.
Now, I have to "plug" myself in with a c# dll. I can change dll2.
The reason is, that functionality in dll2 will over time be implemented in
C# (wrapper DLL) and over time less and less calls will be passed through -
however, it is a pity we cannot touch dll1.
Dll1 does:
MYDBLib::IDatabaseAccessLayerPtr spDBAccess;
hr = spDBAccess.CreateInstance( MyDBLib::CLSID_DatabaseAccessLayer );
and then calls like
hr = spDBAccess->doSomething(&pbstrMyString1, &pbstrMyString2);
or
hr = spDBAccess->doSomethingElse((BSTR)pbstrParameters, &pbstrOut,
&bstrError);
What did I do so far:
I gave DLL2 completely new GUIDs.
Then I made a C# wrapper like this:
[ComVisible(true)]
[Guid("010FA7E6-ABDF-4ECE-BC11-609A16713F4D")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)] //I tried the other
options also
MyDBLib.IDatabaseAccessLayer
public interface IDatabaseAccessLayerWrapper // before it had a :
InheritFromTheOldDll1sInterface
{
//...
void doSomething(out string pbstrMyString1, out string
pbstrMyString2);
void doSomethingElse(string pbstrParameters, out string pbstrOut,
out string pbstrFehler);
//..
}
The interface is complete... I created it by first "inheriting" from the
original DLL-interface (by referencing the c++-based DLL), then having a
class implementing the interface, then using VS2005 "implement interface"
functionality... then used "extract interface".
Now for the rest:
[ComVisible(true)]
[Guid("8D4B28E8-C132-4427-9ED6-B4BFC33C33CA")]
[ClassInterface(ClassInterfaceType.AutoDual)] //tried the other Options
[ProgId("MyDB.DatabaseAccessLayer.1")]
public class DatabaseAccessLayerWrapper : IDatabaseAccessLayerWrapper
{
private MYDBLib.DatabaseAccessLayer oDBAccess; //might switch that
to static later
public DatabaseAccessLayerWrapper()
{
//constructor logic
//might change to use a static oDBAccess-Object in the future
oDBAccess=new DatabaseAccessLayer();
}
public void doSomething(out string pbstrMyString1, out string pbstrMyString2)
{
oDBAccess.doSomething(out pbstrMyString1, out pbstrMyString2);
}
public void doSomethingElse(string pbstrParameters, out string pbstrOut, out
string pbstrFehler)
{
oDBAccess.doSomethingElse(pbstrParameters, out pbstrOut, out pbstrFehler);
}
}
Now...I can access the methods of the wrapper properly doing late binding by
using the progid "MyDB.DatabaseAccessLayer.1" it seems. (I did not check if
the out-parameters are handled properly though since I tested in Scripting
Host JScript and JScript does not support out parameters).
However, from C++ dll (that I cannot even recomplile with a new type library
import since this would be a new dll), the wrapper gets instantiated, the
dll2 gets instantiated, but the calls do not seem to work.
After adding debugging output code, I see that the dll1 calls into wrong
method calls of my wrapper-dll and sometimes the method calls do not seem to
happen at all.
How can I enforce that my c# DLL has the exact same order in the interface
than in the original C++-based dll?
Can I rely on that the interface will be the same order as I read from the
top in the C++-IDL? Would it be enough to simply have the same order in my
interface? Do I also have the same order in my implementation of the
interface (since they are public methods)?
Or do I e.g. use DispId? (If so, which number to start? do the constructors
destructors/finalizers count also?)
Further:
If I would want to mimick the DLL2 completely in C#, how do I achieve this,
since I cannot set a "version independent progid" in C# and I cannot give a
GUID for the type library it seems either.
Do I need to use "out" parameters or can I use "ref"erences also in any way?
I hope I gave enough information so someone can get me on the right track...
Please remember that I cannot change DLL1 at all.
Thanks,
6. GUID-info for: C++ dll1 calls c#-wrapper-dll calls C++ dll2
7. Calling a C++ managed wrapper within C#
Hi, I have wrapped an unmanaged C code in a C++ wrapper. When I call the methods in wrapper everything works perfect but when I add a ref to the wrapper within my C# app and call the wrapper's method there I get a File Not found exception: An unhandled exception of type 'System.IO.FileNotFoundException' occurred in Unknown Module. Additional information: The specified module could not be found. (Exception from HRESULT: 0x8007007E) I am using .NET 2005.
8. Problem calling unmanaged C++ Library from C# through managed wrapper