Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistent results when passing data between C++ DLL and C# GUI

Tags:

c++

c#

dll

I'm still something of a beginner in C#, although I have a reasonable amount of experience with C++. My current project requires that I pass data back and forth between a C++ DLL and a C# GUI. I mostly learned how to do this by reading the responses here on stackoverflow. Unfortunately, I've got a problem that's got me pretty stuck. The DLL is compiled using g++ (gcc version 4.2.1 mingw32-2) and I'm using Visual Studio 2010 to build the GUI.

My problem is that I can get data into C# from some of the DLL functions and not others. The maddening thing is that it appears to be inconsistent, in that some functions work and some don't. To show you what I mean, I've included the C# import code and the C++ export declarations below. I'd really appreciate some advice on this, as I'm really stuck on how to fix this.

This function works fine:

[DllImport("mstTools.dll", EntryPoint = "mstLastError", CallingConvention =    CallingConvention.Cdecl)]
private static extern IntPtr LastError();

public static string mstGetLastError()
{
  return Marshal.PtrToStringAnsi(LastError());
}

It is declared like this in the DLL header:

extern "C" __declspec(dllexport) const char* mstLastError ();

This function doesn't work and returns a null string:

[DllImport("mstTools.dll", EntryPoint = "mstGetMetadata", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetMetadata([MarshalAs(UnmanagedType.LPStr)]string StgMapName);

public static string mstGetMetadata( string StgMapName )
{
  return Marshal.PtrToStringAnsi(GetMetadata( StgMapName ));
}

It is declared in the DLL as follows:

extern "C" __declspec(dllexport) const char* mstGetMetadata ( char* CStgMapName );

Using the Visual Studio debugger, I can see that the imported DLL function (GetMetadata) is returning null.

Conversely, functions that return bool work, for example:

[DllImport("mstTools.dll", EntryPoint = "mstMapExists", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool mstMapExists([MarshalAs(UnmanagedType.LPStr)]string StgMapName);

Which is declared as follows in the DLL:

extern "C" __declspec(dllexport) bool mstMapExists ( char* CStgMapName );

This function works exactly as I expect, in that it returns true/false when it should.

But a function that returns double returns NaN:

[DllImport("mstTools.dll", EntryPoint = "mstGetResolution", CallingConvention =CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.R8)]
public static extern double mstGetResolution([MarshalAs(UnmanagedType.LPStr)]string StgMapName);

which is declared in the DLL as:

extern "C" __declspec(dllexport) double mstGetResolution ( char* CStgName );

Any ideas as to what is happening?

Thanks and regards, Mike

like image 871
MikeWatts Avatar asked Jun 14 '11 04:06

MikeWatts


1 Answers

[DllImport("mstTools.dll", EntryPoint = "mstGetResolution")]
public static extern decimal mstGetResolution([In]string StgMapName);

[DllImport("mstTools.dll", EntryPoint = "mstGetMetadata")]
private static extern IntPtr GetMetadata([In]string StgMapName);
like image 90
Waleed Avatar answered Oct 22 '22 22:10

Waleed