P / Invoke有时会导致使用StringBuilder参数的Win32 1008错误

时间:2012-03-07 15:55:47

标签: c# interop pinvoke

我有一个DLL,我需要P / Invoke以下C方法:

int DAStart(
    HANDLE hOpen,
    char* IPAddress,
    int IPPort,
    int threadPriority,
    char* name,
    char* password,
    char* userName)

使用P / Invoke助手和我自己的研究,我想出了以下C#签名:

[DllImportAttribute("<libName>", EntryPoint="DAStart")]  
static extern  int DAStart(  
    IntPtr hOpen,  
    [MarshalAs(Unmanaged.LPStr)] StringBuilder IPAddress,
    int IPPort,
    int threadPriority, 
    [MarshalAs(Unmanaged.LPStr)] StringBuilder name, 
    [MarshalAs(Unmanaged.LPStr)] StringBuilder password,   
    [MarshalAs(Unmanaged.LPStr)] StringBuilder userName);

现在,我正在通过以下方式进行呼叫:

int port = 3000;
int threadPriority = 20;

DAStart(
    this.nativeDllHandle, // an IntPtr class field  
    new StringBuilder("10.0.10.1"),
    int port,
    int threadPriority,
    new StringBuilder("admin"),
    new StringBuilder("admin"),
    new StringBuilder("admin"));

现在,有时这很好用,但是在调用此库时,我得到了Win32错误1008 - An attempt was made to reference a token that does not exist

可能是我的StringBuilder对象被垃圾收集,以便在本机代码尝试使用它时引用不再存在?我应该为每一个提供参考吗?

在这种情况下,IntPtr会更好地传递我的字符串吗?

** 更新 **

这是我为DAStart提供的所有API文档:

输入
HANDLE hInfo DAOpen返回的句柄
char * IPAdress_in TMEE服务器的IP地址
int IPPort控制台TMEE服务器端口(默认为端口3000)
int threadPriority发送文件线程的线程优先级 char * name未在硬件DLL中使用 char *密码未在硬件DLL中使用 char * username未在硬件DLL中使用

返回
ERROR_SUCCESS 0
ERROR_BAD_HANDLE -1
ERROR_BIND_FAILED -10

评论
DAStart API将客户端DLL连接到活动的TMEE Server服务。启动客户端线程时,优先级设置为threadPriority参数。 IP地址参数必须设置为TMEE服务器的地址。必须将port参数设置为TMEE Server侦听Console连接的端口(控制台使用的默认端口为3010)。启动Console线程时,优先级设置为threadPriority参数。

2 个答案:

答案 0 :(得分:2)

在评论中,您指出DLL会获取char*指针的副本(而不是字符串的内容),然后在 {{1>之后修改字符串的内容返回。

面对这种非常规的界面设计,您唯一的选择是掌控字符串参数的编组。您无法使用DAStart,因为传递给本机代码的StringBuilder仅在pinvoke调用期间有效。在pinvoke调用返回后,不能依赖它是有效的。

因此,您唯一的解决方案是将字符串参数传递为char*。使用IntPtr分配内存。将生成的Marshal.StringToHGlobalAnsi传递给IntPtr。当您确定DLL已完成指针时,请使用DAStart解除分配。

答案 1 :(得分:-2)

垃圾收集器不知道托管环境之外的引用。
因此,只要您需要对象,就需要在某处保留一个额外的引用 - 最简单的方法是通过调用类中的静态属性。
IntPtr没有什么区别 - 它也会被收集。