• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 930
  • Last Modified:

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.
0
PacificaResearch
Asked:
PacificaResearch
  • 6
  • 2
1 Solution
 
satsumoSoftware DeveloperCommented:
The calling code does not call test_msg?
0
 
PacificaResearchAuthor Commented:
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().
0
 
satsumoSoftware DeveloperCommented:
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.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
PacificaResearchAuthor Commented:
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.
0
 
PacificaResearchAuthor Commented:
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.
}
0
 
PacificaResearchAuthor Commented:
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!
0
 
PacificaResearchAuthor Commented:
I created two Visual Studio solutions for this issue, one for console and the other for .DLL. They are virtually identical. The console solution works fine. The .dll solution blows up.

I began making changes in the compiler and linker settings for the .exe that calls the initial .dll. I didn't make the changes for any particular reason; the initial settings were already correct. Eventually I came across settings that made the .dll work. When I restored the settings to their original values, the .dll continued to work. When I remade the solution, the .dll blows up. There seems to be something unstable in C++ interop. I'll put up with it until something better comes along.
0
 
PacificaResearchAuthor Commented:
No expert had any useful advice.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now