Calling C++ dll from C# returns junk characters

2019-09-09 12:06发布

问题:

I am new to C++.

And I am developing a just simple dll.

I have to C++ function from C# with a file location information which should be string.

And C++ returns some string to C#.

Here are my codes..

extern "C" __declspec(dllexport) const char* ParseData(char *filePath)
{
    string _retValue(filePath);

    printf(_retValue.c_str());  //--> this prints ok

    return _retValue.c_str();
}






[DllImport("D:\\Temp\\chelper.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr ParseData(string s);


static void Main(string[] args)
{
    string s    = "D:\\Temp\\test.bin";
    string ret  = Marshal.PtrToStringAnsi(ParseData(s));
    Console.WriteLine(ret);
}

When I look into the string that C++ returns, it looks like below.

硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼硼

I am expecting "D:\Temp\test.bin" which I passed to C++ dll.

What's wrong with my code?

回答1:

Your problem is that you're trying to return a local variable. Your DLL has access to that memory because it declared the variable, but the C# program can't access it so it's getting garbage instead. Look into how the Windows API does it: have the caller pass you a buffer and the size of that buffer, and store your results there instead. Something like this (untested):

extern "C" __declspec(dllexport) void ParseData(char* filePath, int pathSize)
{
  char workingPath[pathSize + 1]; //leave space for a trailing null

  strncpy(workingPath, filePath, pathSize);

  //do whatever parsing you need to do here

  strncpy(filePath, workingPath, pathSize);
}

Or just work directly with the passed filePath buffer. But however you choose to do it, make sure you're writing your final result into the buffer you got from the caller, not a local variable.