将Clarion Procedure声明转换为C#DLLImport
如何将此Clarion过程声明转换为C#? 它是用C编写的第三方DLL的一部分,它没有太多文档。 我已经列出了正常工作的Clarion方法的原型。 在C#中,我不确定用什么类型替换*CString
。 我试过像@DanielC建议的char[]
,但它没有用。 我还发现Clarion long
是32位(感谢@ shf301)。
号角:
SendRequest Procedure(*CString xData,Long DataLen,Long xTimeout),Byte,Virtual
C#(我试过的,哪个不起作用):
[DllImport("3RD_PARTY_API.dll")] private static extern long SendRequest(ref string xData, int DataLen, int xTimeout);
当我在C#中调用SendRequest
方法时,我从VS2010获得了标准的PInvokeStackImbalance检测错误。 我认为这是参数类型的问题,而不是DllImport声明中的CharSet
或EntryPoint
。 我真的只是坚持如何将*CString
转换为有效的C#类型。
我找到了答案。 我希望我仍然与编写此代码的开发人员合作,因此我可以对他们大喊大叫。 他们在API周围放置了一个包装器,以便我列出的带有3个参数的方法然后调用没有超时值的实际API。 PInvokeStackImbalanceexception来自我添加额外参数的事实。
这是实际的Clarion过程以及正确的C#语法:
号角:
SendRequest Procedure(*CString xData, Long DataLen), Byte, Virtual
C#:
[DllImport("NOVA_API.dll", EntryPoint = "SendRequest")] private static extern byte SendRequest(string xData, int DataLen);
总之,Clarion *CString
可以在DLLImport声明中转换为.NET string
类型。
非常感谢那些回应的人。 这是我在搜索中使用的其他资源,我发现它非常有用: pinvoke.net
在C#中, long
总是64位。 Clarion中的Long
是32位。 将p / Invoke声明中的long
参数更改为int
。
根据维基百科,clarion可以使用一些奇怪的TopSpeed“双快速呼叫”,他们使用4 reg参数而不是两个。 如果使用此调用约定编译代码,则无法直接从C#调用。
TopSpeed / Clarion / JPI前四个整数参数在寄存器eax,ebx,ecx和edx中传递。 浮点参数在浮点堆栈上传递 – 寄存器st0,st1,st2,st3,st4,st5和st6。 结构参数始终在堆栈上传递。 寄存器耗尽后,其他参数将在堆栈上传递。 在ex中返回整数值,在edx中返回指针,在st0中返回浮点类型。
如果不是这种情况,则可能是您的一个参数不是正确的大小,否则您将获得AV而不是损坏的堆栈错误。
也可以尝试在dllimport上设置调用约定。 除了“TOPSPEED”之外,clarion还支持stdcall和cdecl,但“TOPSPEED”是默认值。 下面是与vb6和clarion互操作的教程的链接。
你试过char[]
吗? 我不确定它会起作用,但值得一试。 (我发布此评论但我没有权利)