Link to home
Start Free TrialLog in
Avatar of PacificaResearch
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.
Avatar of Member_2_5069294
Member_2_5069294

The calling code does not call test_msg?
Avatar of PacificaResearch

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().
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.
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.
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.
}
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!
ASKER CERTIFIED SOLUTION
Avatar of PacificaResearch
PacificaResearch

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No expert had any useful advice.