我目前正在IT公司工作。他们使用Clarion制作软件, 在那个软件中,他们有一个DLL,可以从他们的数据库中重新计算很多值。我需要从我的C#项目中调用这个DLL。没有工作,我尝试了一切。
我的代码如下:
public partial class Form1 : Form
{
[DllImport("EPNORM.dll", EntryPoint = "MyRecalcualate@FlOUcOUcOsbOUc")]
public static extern void MyRecalcualate(System.Int64 myPtr, System.Int64 myLong, CWByte myByte);
[DllImport("User32.dll")]
public static extern Boolean MessageBeep(UInt32 beepType);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
System.Int64 myPtrTemp = 1234;
System.Int64 myLongTemp = 5678;
System.Byte myByteTemp = 88;
try
{
MyRecalcualate(myPtrTemp, myLongTemp, myByteTemp);
bool messagebeep = MessageBeep(1);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
MessageBox.Show("Successful");
}
}
}
问题是当我用断点调用它时,它会消失在MyRecalcualate
方法中并在2秒后到达finallly
块并重新显示而不从DLL执行任何操作。这是因为我需要修复DLL方法中的某些内容,或者因为我的调用错误了吗?
以下调用的参数是:MyRecalculate(LONG,LONG,BYTE)
MyRecalcualate PROCEDURE (MyStringPtr, MyLong, MyByte) ! Declare Procedure
LOC:CString CSTRING(255)
LOC:Byte BYTE
CODE
! clear completely LOC:CString with null values
LOC:CString = ALL('<0>', SIZE(LOC:CString))
! load string value, byte by byte, from memory address passed (MyStringPtr) and put into LOC:CString
I# = 0
LOOP
PEEK(MyStringPtr + I# , LOC:Byte)
IF LOC:Byte = 0 THEN BREAK END
LOC:CString[I# + 1] = CHR(LOC:Byte)
I# += 1
END
MESSAGE('MyString value is:||' & CLIP(LOC:CString))
MESSAGE('MyLong value is:||' & MyLong)
MESSAGE('MyByte value is :||' & MyByte)
这是他们签约的开发人员给我发的关于参数以及他如何在VB.NET中调用它的截图: VB.NET代码:http://imageshack.us/photo/my-images/269/callfromvisualbasictocl.jpg/ CLARION中的参数:http://imageshack.us/photo/my-images/100/asdxg.jpg/
答案 0 :(得分:2)
第一个参数是指向以null结尾的字符串的指针。您不能只传递随机Int64
值。所以你的pinvoke应该是这样的:
[DllImport("EPNORM.dll", EntryPoint = "MyRecalcualate@FlOUcOUcOsbOUc")]
public static extern void MyRecalcualate(string myPtr, int myInt, byte myByte);
我相信第二个参数Clarion LONG
是一个32位整数。所以在C#方int
。更重要的是,你需要仔细检查Clarion方面的调用约定。您确定它是stdcall
,这是您的C#使用的。