AccessViolation,当从C ++ / CLI调用C ++ - DLL时 [英] AccessViolation, when calling C++-DLL from C++/CLI

查看:151
本文介绍了AccessViolation,当从C ++ / CLI调用C ++ - DLL时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



但是,当我调用一个函数时,它会在C#取一个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;
}

EDIT 1 END
$ b

编辑2



我也尝试过PtrToStringChars以下方式(感谢Matt, href =http://msdn.microsoft.com/en-us/library/d1ae6tz5%28v=VS.90%29.aspx =nofollow>此处):

  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 END



一些相关的问题在这里,但没有找到解决方案。



任何提示?
谢谢。

解决方案

Simon,
我试过了你的例子,违反。这是我的代码:

 使用命名空间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()
{
包装器
String ^ p = gcnew String(Hello);
wrapper.Net_methodX(0,p,0);
}

此外,我有几个意见:


  1. 请点击此处: http://support.microsoft。 com / kb / 311259

  2. 您正在使用pin_ptr作为本机内存。 StringToHGlobalAnsi方法返回本机内存,所以我不认为使用pin_ptr在这里有意义。如果你使用一个方法给你一个指向托管内存的指针(如PtrToStringChars),pin_ptr将是有意义的。除非你正在修改字符串,否则你可能想要使用PtrToStringChars方法 - 以避免不必要的分配和复制。

  3. 你会发布一个示例版本的methodX导致问题?如果我能重现这个问题,我可能会更有帮助。


I've written a C++/CLI wrapper for a C++-DLL to use this DLL in a C# programm.

However, when I call a function, which takes a char* I get a 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;
}

The signature of the C++-function is

int methodX(int a, char *Key, long v);

EDIT 1

Just to "pin" like the following didn't work either:

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;
}

EDIT 1 END

EDIT 2

I tried also PtrToStringChars the following way (Thanks Matt, found also some doc 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 still occurs, maybe it's an error in methodX() (which is a Third-party-DLL).

EDIT 2 END

I have read some related questions here, but did not find a solution yet.

Any hints? Thank you.

解决方案

Simon, I tried out your example and I do not get an Access Violation. Here's my code:

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);
}

Also, I have a few comments:

  1. Read here: http://support.microsoft.com/kb/311259
  2. You are using a pin_ptr to native memory. The StringToHGlobalAnsi method returns native memory, so I don't think using a pin_ptr makes sense here. A pin_ptr would make sense if you were using a method that gives you back a pointer to managed memory (like PtrToStringChars). Unless you are modifying the string, you probably want to go with the PtrToStringChars approach anyways--to avoid unnecessary allocation and copying.
  3. Would you post an example version of methodX that causes the problem? If I can reproduce the issue, I might be able to be more helpful.

这篇关于AccessViolation,当从C ++ / CLI调用C ++ - DLL时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆