本文介绍了从C#调用C ++ dll返回垃圾字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C ++的新手。



我正在开发一个简单的dll。



我有



然后C ++将一些字符串返回到C#。



这是我的代码。

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

printf(_retValue.c_str()); //->这样可以打印

return _retValue.c_str();
}






[DllImport( D:\\Temp\\chelper。 dll,CallingConvention = CallingConvention.Cdecl)]
私有静态外部IntPtr ParseData(string s);


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

当我查看C ++返回的字符串时,如下所示。 / p>

铜硼硼硼硼硼



我期望传递给的 D:\Temp\test.bin C ++ dll。



我的代码怎么了?

解决方案

您的问题是您正在尝试返回局部变量。您的DLL可以访问该内存,因为它声明了变量,但是C#程序无法访问该变量,因此它会变成垃圾。研究Windows API的工作方式:让调用者向您传递一个缓冲区和该缓冲区的大小,然后将结果存储在那里。这样的东西(未经测试):

  extern C __declspec(dllexport)void ParseData(char * filePath,int pathSize)
{
char workingPath [pathSize + 1]; //为尾随的空

留出空间strncpy(workingPath,filePath,pathSize);

//做任何您需要在这里进行的解析

strncpy(filePath,workingPath,pathSize);
}

或者直接使用传递的 filePath 缓冲区。但是,无论您选择执行哪种操作,请确保将最终结果写入从调用方获得的缓冲区中,而不是局部变量。


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?

解决方案

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.

这篇关于从C#调用C ++ dll返回垃圾字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 09:15