将字符串数组从c#传递到c++ dll,然后再返回
pass an array of strings from C# to a C++ dll and back again
我看了一下googleverse和堆栈溢出,看到了几个类似的问题,但我找到的答案都不适合我。我是一个新成员,所以我不允许评论别人问题的答案来要求澄清,所以我不得不求助于问我自己的问题。
好的,所以我试图从c#应用程序传递字符串数组到c++ dll,然后在另一个c#应用程序中获取该信息。我相信我传递到c++正确,但我不能得到正确的字符串从dll返回。
我像这样传递给c++:
[DllImport("KinectPlugins.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void SetGrammarData(string[] strArr, int size);
public void SetGrammar(string[] strArr)
{
SetGrammarData(strArr, strArr.Length);
}
我的c++代码是这样的:
#define EXPORT_API __declspec(dllexport)
#pragma data_seg(".SHARED")
char** grammarData;
int grammarDataLength = 0;
#pragma data_seg()
#pragma comment(linker, "/section:.SHARED,RWS")
EXPORT_API void SetGrammarData(char** strArr, int size)
{
grammarData = strArr;
grammarDataLength = size;
}
EXPORT_API int GetGrammarDataLength()
{
return grammarDataLength;
}
EXPORT_API char** GetGrammarData()
{
return grammarData;
}
我在其他c#应用程序中获取信息的代码如下:
[DllImport("KinectPlugins.dll")]
private static extern IntPtr GetGrammarData();
[DllImport("KinectPlugins.dll")]
private static extern int GetGrammarDataLength();
public string[] GetGrammar()
{
int size = GetGrammarDataLength();
List<string> list = new List<string>();
IntPtr ptr = GetGrammarData();
IntPtr strPtr;
for (int i = 0; i < size; i++)
{
Console.WriteLine("i = " + i);
strPtr = Marshal.ReadIntPtr(ptr);
list.Add(Marshal.PtrToStringAnsi(strPtr));
ptr += Marshal.SizeOf(typeof(IntPtr));
}
return list.ToArray();
}
根据我的研究,理论上这应该是可行的,因为我已经看到其他几个人使用了几乎相同的代码。实际上,我传入的是:
SetGrammar(new string[] { "b", "a" });
从另一边返回的是:
stringArray[0] =
stringArray[1] = H-▬l☺
以防某些人由于某些原因无法查看它或另一个stringArray[1]等于H, -,粗线,l和笑脸符号。这显然不是我输入的。
有没有人知道我在哪里可能会出错?我已经绞尽脑汁解决这个问题很长一段时间了,我真的需要一些帮助,因为我感觉我在这里错过了一些非常简单的东西。
编辑:根据antijon的建议,我确实改变了我的SetGrammarData来复制字符串,但我仍然遇到了一个问题。
新代码:(inside the data_seg)
wchar_t* grammarData;
(end data_seg)
EXPORT_API void SetGrammarData(wchar_t* strArr, int size)
{
delete[] grammarData;
grammarData = new wchar_t[size];
std::memcpy(grammarData, strArr, sizeof(wchar_t) * size);
grammarDataLength = size;
}
EXPORT_API wchar_t* GetGrammarData()
{
return grammarData;
}
现在我得到了这样的输出:
stringArray[0] = 8
stringArray[1] =
c#代码保持不变。我是否还遗漏了什么需要改变的地方?
Edit2: 刚刚意识到wchar_t像一个字符,而不是字符串,不知道为什么我认为它像字符串。回到绘图板,需要弄清楚如何最好地复制wchar_t**。没有经验的c++,但我不认为这是不可能得到一个wchar_t*的长度不传递给我自己,但我将不得不研究它。
Edit3: 终于能正常工作了
最后的结果是:
(inside the data_seg)
std::wstring* grammarData;
(end data_seg)
EXPORT_API void SetGrammarData(wchar_t** strArr, int size)
{
delete[] grammarData;
grammarDataLength = size;
grammarData = new std::wstring[size];
for(int i = 0; i < size; i++)
{
grammarData[i] = std::wstring(strArr[i]);
}
}
EXPORT_API const wchar_t** GetGrammarData()
{
const wchar_t** wct = new const wchar_t*[grammarDataLength];
for(int i = 0;i<grammarDataLength;i++)
{
const wchar_t* t = grammarData[i].c_str();
wct[i] = t;
}
return wct;
}
标:我以为它能正常工作,是错误的。我正在测试一个传递回自身的exe,但当通过dll传递到另一个exe时,什么也不会通过。我现在让它工作了:
(inside the data_seg)
wchar_t grammarData[32][50] = {};
(end data_seg)
EXPORT_API void SetGrammarData(wchar_t** strArr, int size)
{
grammarDataLength = size;
for(int i = 0; i < size; i++)
{
wcscpy(grammarData[i], strArr[i]);
}
grammarDataChanged = 1;
}
EXPORT_API wchar_t** GetGrammarData()
{
wchar_t** wct = new wchar_t*[grammarDataLength];
for(int i = 0;i<grammarDataLength;i++)
{
wct[i] = grammarData[i];
}
grammarDataChanged = 0;
return wct;
}
这里有几个可能的问题:
- 默认情况下,. net将封送为
wchar_t
,而不是char
。你需要用MarshalAsAttribute标记你的输入/输出字符串参数来使用char。 - 如果你想保留字符串,你需要在C函数中复制它们。在
SetGrammarData
的函数调用中给你的指针不能保证持续存在。
相关文章:
- 挂起和取消挂起一个文件DLL
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 从C++dll访问C#中的一行主要参数
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- C++:将外部库链接到dll库
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 不同的Visual Studio版本中缺少.dll
- 从DLL中删除类的实例
- 如何包装第三方DLL在R中使用
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Python ctypes:不会按预期加载 dll
- 在 C++/CLI 中将 .NET 事件从一个 DLL 引发到另一个 DLL