将Clarion Procedure声明转换为C#DLLImport

时间:2012-10-29 22:08:04

标签: c# pinvoke clarion

如何将此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 was detected错误。我认为这是参数类型的问题,而不是DllImport declaration中的CharSetEntryPoint。我真的只是坚持如何将*CString转换为有效的C#类型。

4 个答案:

答案 0 :(得分:4)

我找到了答案。我希望我仍然与编写此代码的开发人员合作,因此我可以对他们大喊大叫。他们在API周围放置了一个包装器,以便我列出的带有3个参数的方法然后调用没有超时值的实际API。 PInvokeStackImbalance异常来自我添加额外参数的事实。

以下是实际的Clarion过程以及正确的C#语法:

Clarion:

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

答案 1 :(得分:3)

在C#中,long总是64位。 Clarion中的Long是32位。将p / Invoke声明中的long参数更改为int

答案 2 :(得分:2)

根据维基百科,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的互操作教程的链接。

http://pisoft.ru/verstak/insider/cw_vb.htm

答案 3 :(得分:1)

你试过char[]吗?我不确定它会起作用,但值得一试。 (我发布此评论作为评论,但我没有权利)