我为C ++编写了一个C ++ / CLI包装器 - 在C#程序中使用此DLL。
但是,当我调用一个char *函数时,我得到一个AccessViolation
int Wrapper::Net_methodX(int a, String^ key, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(key);
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
int val = methodX(a,cKey, v); // AccessViolation here
Marshal::FreeHGlobal(ptr);
return val;
}
C ++函数的签名是
int methodX(int a, char *Key, long v);
编辑1
就像下面的“pin”一样也不起作用:
int Wrapper::Net_methodX(int a, String^ key, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(key);
char* cKey = static_cast<char*>(ptr.ToPointer());
pin_ptr<char> pinned = cKey;
int val = methodX(a,cKey, v);
Marshal::FreeHGlobal(ptr);
return val;
}
编辑1结束
编辑2
我还尝试了以下方式的PtrToStringChars(感谢Matt,也发现了一些文档here):
int Wrapper::Net_methodX(int a, String^ key, long v)
{
pin_ptr<const wchar_t> wkey = PtrToStringChars(key);
size_t convertedChars = 0;
size_t sizeInBytes = ((key->Length + 1) * 2);
errno_t err = 0;
char * ckey = (char * ) malloc(sizeInBytes);
err = wcstombs_s(&convertedChars, ckey, sizeInBytes, wkey, sizeInBytes);
int val = methodX(A_Symbol_Table,ckey, Value);
return val;
}
仍然会发生AccessViolation,可能是methodX()(第三方DLL)中的错误。
编辑2结束
我在这里已经阅读了一些相关的问题,但还没有找到解决方案。
任何提示? 谢谢。
答案 0 :(得分:2)
我知道这是一个老问题,但对于那些偶然发现这个问题寻找答案的人来说,这里有一些更简单的解决方案。
sprintf
进行如下转换:sprintf(cStr, "%s", clrString);
。有关完整示例,请参阅my answer to this question。marshal_as<>
(KB中的方法#4)。它比该文件中的其他方法简单得多。答案 1 :(得分:0)
西蒙
我认为以下代码存在问题
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
您可能需要阅读此http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/0bd049fe-844a-4cb6-b9f6-c8f5107bc957
让我知道它是否对你有帮助。
Sujay
答案 2 :(得分:0)
西蒙 我尝试了你的例子,我没有得到访问冲突。这是我的代码:
using namespace System;
using namespace System::Runtime::InteropServices;
ref class Wrapper
{
public:
static int Net_methodX(int a, String^ key, long v);
};
int methodX(int a, char * pKey, long v)
{
IntPtr ptr = static_cast<IntPtr>(pKey);
String ^ pString = Marshal::PtrToStringAnsi(ptr);
System::Console::WriteLine(pString);
return a;
}
int Wrapper::Net_methodX(int a, String^ pKey, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(pKey);
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
int val = methodX(a,cKey, v); // AccessViolation here
Marshal::FreeHGlobal(ptr);
return val;
}
void main()
{
Wrapper wrapper;
String ^ p = gcnew String("Hello");
wrapper.Net_methodX(0, p, 0);
}
另外,我有几点意见: