PacificaResearch
asked on
unmanaged calling managed fails in DLL
Hi,
I'm attempting to call managed code from unmanaged through a simple DLL interface. Microsoft docs claim (again and again) that this works fine but provide no examples. I set up an extremely simple console app that works fine (below). I put the same tiny bit of code in a DLL, set every compiler setting identical to the console app (CLR on), and it fails. It blows up deep in Windows with an undefined error.
I'm using VS-2010, .NET 4.0, Windows 7 64bit.
Here are the code samples:
Console app that works fine:
// hello.cpp : main project file.
using namespace System;
int write_msg(wchar_t *MSG1,wchar_t *MSG2);
#pragma unmanaged
int main()
{
write_msg(L"Hello World",L"How is it going?");
return (0);
}
#pragma managed
int write_msg(wchar_t *MSG1,wchar_t *MSG2)
{
String^ msg1 = gcnew String(MSG1);
String^ msg2 = gcnew String(MSG2);
Console::WriteLine(msg1);
Console::WriteLine(msg2);
return 0;
}
Here's the DLL code that fails:
// This is the main DLL file.
using namespace System;
extern "C"
{
void test_msg(wchar_t*,wchar_t* );
}
int write_msg(wchar_t *MSG1,wchar_t *MSG2);
#pragma unmanaged
void test_msg(wchar_t *msg1,wchar_t *msg2)
{
write_msg(msg1,msg2);
}
#pragma managed
int write_msg(wchar_t *MSG1,wchar_t *MSG2)
{
String^ msg1 = gcnew String(MSG1);
String^ msg2 = gcnew String(MSG2);
return (0);
}
When debugging, control gets to the unmanaged function test_msg(), and the arguments are correct. The error occurs when test_msg() tries to call write_msg().
A clue, perhaps. In the console app, I can set breakpoints on any line in the managed or unmanaged sections. In the DLL I can set breakpoints only in the unmanaged section.
I'm attempting to call managed code from unmanaged through a simple DLL interface. Microsoft docs claim (again and again) that this works fine but provide no examples. I set up an extremely simple console app that works fine (below). I put the same tiny bit of code in a DLL, set every compiler setting identical to the console app (CLR on), and it fails. It blows up deep in Windows with an undefined error.
I'm using VS-2010, .NET 4.0, Windows 7 64bit.
Here are the code samples:
Console app that works fine:
// hello.cpp : main project file.
using namespace System;
int write_msg(wchar_t *MSG1,wchar_t *MSG2);
#pragma unmanaged
int main()
{
write_msg(L"Hello World",L"How is it going?");
return (0);
}
#pragma managed
int write_msg(wchar_t *MSG1,wchar_t *MSG2)
{
String^ msg1 = gcnew String(MSG1);
String^ msg2 = gcnew String(MSG2);
Console::WriteLine(msg1);
Console::WriteLine(msg2);
return 0;
}
Here's the DLL code that fails:
// This is the main DLL file.
using namespace System;
extern "C"
{
void test_msg(wchar_t*,wchar_t*
}
int write_msg(wchar_t *MSG1,wchar_t *MSG2);
#pragma unmanaged
void test_msg(wchar_t *msg1,wchar_t *msg2)
{
write_msg(msg1,msg2);
}
#pragma managed
int write_msg(wchar_t *MSG1,wchar_t *MSG2)
{
String^ msg1 = gcnew String(MSG1);
String^ msg2 = gcnew String(MSG2);
return (0);
}
When debugging, control gets to the unmanaged function test_msg(), and the arguments are correct. The error occurs when test_msg() tries to call write_msg().
A clue, perhaps. In the console app, I can set breakpoints on any line in the managed or unmanaged sections. In the DLL I can set breakpoints only in the unmanaged section.
The calling code does not call test_msg?
ASKER
As I wrote:
When debugging, control gets to the unmanaged function test_msg(), and the arguments are correct. The error occurs when test_msg() tries to call write_msg().
When debugging, control gets to the unmanaged function test_msg(), and the arguments are correct. The error occurs when test_msg() tries to call write_msg().
The code for the console app calls write_msg(). In the DLL code, write_msg() is not external and it does not call test_msg(). So I don't understand how control can reach test_msg() given the code shown.
ASKER
In the DLL, test_msg() is external and unmanaged and called by some outside unmanaged code. That part works fine. Control arrives at test_msg() and the arguments are correct.
There is a prototype for write_msg(), to satisfy the compiler, and test_msg() attempts to call write_msg(), which fails. The problem is between test_msg() (unmanaged) and write_msg() (managed).
In the console app, the main() function is the equivalent of the test_msg() function.
There is a prototype for write_msg(), to satisfy the compiler, and test_msg() attempts to call write_msg(), which fails. The problem is between test_msg() (unmanaged) and write_msg() (managed).
In the console app, the main() function is the equivalent of the test_msg() function.
ASKER
I simplified the DLL code to the absolute minimum and it still blows up the same way. Every Microsoft article I read about C++ interop states that mixed-mode DLLs "just work" as long as you compile with /clr. In this sample, I'm not passing any arguments, not returning any result, not executing ANY code except the call to write_msg(), and the blowup is the same as before.
Please, any help at all would be much appreciated!
All of the articles I find on the web or MS knowledgebase seem to pertain to VS-2003 or VS-2005. Did Microsoft remove C++ interop from VS-2010 and Windows 7? The compiler doesn't report any problems with this code, and the debugger steps to the test_msg() function. It can't step to write_msg() without blowing up.
Is it possible for an expert to compile and step this sample to see the result?
// Bridge.cpp - compiles to bridge.dll.
using namespace System;
extern "C"
{
void test_msg();
}
void write_msg(); // Prototype for write_msg (below)
#pragma unmanaged
void test_msg()
{
// Debugger stops here without error.
write_msg();
}
#pragma managed
void write_msg()
{
// Function does nothing, still blows up.
}
Please, any help at all would be much appreciated!
All of the articles I find on the web or MS knowledgebase seem to pertain to VS-2003 or VS-2005. Did Microsoft remove C++ interop from VS-2010 and Windows 7? The compiler doesn't report any problems with this code, and the debugger steps to the test_msg() function. It can't step to write_msg() without blowing up.
Is it possible for an expert to compile and step this sample to see the result?
// Bridge.cpp - compiles to bridge.dll.
using namespace System;
extern "C"
{
void test_msg();
}
void write_msg(); // Prototype for write_msg (below)
#pragma unmanaged
void test_msg()
{
// Debugger stops here without error.
write_msg();
}
#pragma managed
void write_msg()
{
// Function does nothing, still blows up.
}
ASKER
I really can't make this question any simpler.
The Microsoft documentation, such as it is, clearly states that C++ interop with /clr compiler option allows unmanaged C++ to call managed C# directly, in the same .DLL, using the #pragma managed and #pragma unmanaged operators.
Has anyone ever had any success with this?
Is Microsoft simply lying about their capabilities? Are they smoking something here in Washington state?
Has anyone looked at the very simple sample code I posted above? It compiles fine, and blows up. It doesn't work. It should work, unless the documentation is just not true.
Any help or suggestions would be much appreciated. Thanks!
The Microsoft documentation, such as it is, clearly states that C++ interop with /clr compiler option allows unmanaged C++ to call managed C# directly, in the same .DLL, using the #pragma managed and #pragma unmanaged operators.
Has anyone ever had any success with this?
Is Microsoft simply lying about their capabilities? Are they smoking something here in Washington state?
Has anyone looked at the very simple sample code I posted above? It compiles fine, and blows up. It doesn't work. It should work, unless the documentation is just not true.
Any help or suggestions would be much appreciated. Thanks!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
No expert had any useful advice.