Bruno said:
Have you tried to do this before, Jeroen?
No, never. I have boundless confidence in this working, though.
It turns out my advice is misleading; you don't export unmanaged functions
since you can't call managed code from unmanaged functions (duh). Exporting
the managed functions directly works.
Yes. I'm going to go command-line, if you don't mind, as it's more
reproducible than project files. You may have to puzzle around a bit if you
want to use the GUI to achieve the same results.
We'll have three artifacts: a managed DLL, an unmanaged DLL linking to the
managed DLL and a little EXE to call a function in the unmanaged DLL.
ManagedLibrary.cpp:
using namespace System;
ref class Foo {
public:
static void Test() {
Console::WriteLine("Hello from the managed world.");
}
};
extern "C" __declspec(dllexport) void __stdcall test(void) {
Foo::Test();
}
UnmanagedLibrary.cpp:
#include <stdio.h>
extern "C" __declspec(dllimport) void __stdcall ManagedHello(void);
extern "C" __declspec(dllexport) void __stdcall hello(void) {
printf("Hello from the unmanaged world.\n");
ManagedHello();
}
program.cpp:
#include <stdio.h>
extern "C" __declspec(dllimport) void __stdcall hello(void);
int main() {
hello();
}
Now let's link it all together. First the managed DLL:
cl /clr ManagedLibrary.cpp /link /dll /out:ManagedLibrary.dll
We're not done! We need to embed the library manifest in the DLL, because
for some reason the linker won't do it for us:
mt /manifest ManagedLibrary.dll.manifest
/outputresource:ManagedLibrary.dll;#2
Without this step, you will get CRT initialization errors. Now the unmanaged
DLL:
cl UnmanagedLibrary.cpp ManagedLibrary.lib /link /dll
/out:UnmanagedLibrary.dll
Finally the EXE:
cl program.cpp UnmanagedLibrary.lib
Running the EXE:
Hello from the unmanaged world.
Hello from the managed world.
And that's all there is to it! Well, when it works.