Steve Terepin wrote:
Could someone confirm that I've understood this properly ? I'm writing some
Managed C++ code that provides a wrapper around some existing native C++
code that makes use of the standard C library and also invokes routines in a
3rd-party LIB. This code will be built into an assembly that will be called
from a front-end GUI written in C#. Therefore, I *do* need to follow all the
guidelines in 814472, and explicitly call an initialisation function from my
GUI app. Yes ?
That is indeed what it says in KB 814472.
Given that this is the case, is there a way of having the initialisation
code automatically invoked when the assembly is loaded ? Relying on client
code to call the initialisation function seems rather ugly :-(
You can avoid all of this ugliness by not using mixed DLLs in the first
place. You can write a pure native Win32 DLL that wraps your C++ code
and exposes it as a P/Invoke-friendly flat API. For example:
==== CppLibrary.DLL ================================================== ==
__declspec(dllexport) class MyClass {
public:
MyClass(int x) { ... }
~MyClass();
void DoStuff();
};
==== End CppLibrary.DLL ================================================
==== Wrapper.DLL ================================================== =====
extern "C" __declspec(dllexport) MyClass *CreateMyClass(int x) {
return new MyClass(x);
}
extern "C" __declspec(dllexport) void DeleteMyClass(MyClass *myClass) {
delete myClass;
}
extern "C" __declspec(dllexport) void MyClassDoStuff(MyClass *myClass) {
myClass->DoStuff();
}
==== End Wrapper.DLL ================================================== =
==== C# Client ================================================== =======
class MyClass : IDisposable {
[DllImport("Wrapper.DLL")]
extern static IntPtr CreateMyClass(int x);
[DllImport("Wrapper.DLL")]
extern static void DeleteMyClass(IntPtr myClass);
[DllImport("Wrapper.DLL")]
extern static void MyClassDoStuff(IntPtr myClass);
IntPtr handle;
public MyClass(int x) {
handle = CreateMyClass(x);
}
public void Dispose() {
DeleteMyClass(handle);
}
public void DoStuff() {
MyClassDoStuff(handle);
}
}
==== End C# Client ================================================== ===
Advantages of this approach:
- no mixed DLLs, ergo no mixed DLL bugs
- no need for explicit initialization
- transparency: no It Just Works magic or surprises
- easier to see where managed-unmanaged transitions occur, which is
important for performance
Advantages of mixed DLLs (a.k.a. It Just Works):
- type fidelity between managed and unmanaged worlds:
- static type checking
- native data structures can be accessed as usual in managed functions
Good luck!
Bart Jacobs