I am currently working on a at an IT company. They made their software using Clarion, and in that software they have a DLL which recalculates a lot of values from their database. I need to call this DLL from my C# project. I tried everything without it working.
My code is as below:
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");
}
}
}
The problem is when I call it with breakpoints, it just disappears into the MyRecalcualate
method and reaches the finallly
block after 2 seconds and re-displays without doing anything from the DLL. Is this because there is something in the DLL method I need to fix or because I am doing the call wrong?
The parameters to the call below is : 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)
This is the screenshot their contracted developer mailed me of the parameters and how he calls it in VB.NET: VB.NET CODE: http://imageshack.us/photo/my-images/269/callfromvisualbasictocl.jpg/ PARAMETERS IN CLARION: http://imageshack.us/photo/my-images/100/asdxg.jpg/
The first parameter is a pointer to a null-terminated character string. You can't just pass a random Int64
value. So your pinvoke should look like this:
[DllImport("EPNORM.dll", EntryPoint = "MyRecalcualate@FlOUcOUcOsbOUc")]
public static extern void MyRecalcualate(string myPtr, int myInt, byte myByte);
I believe that the second parameter, the Clarion LONG
, is a 32 bit integer. So int
on the C# side. What's more, you need to double check the calling convention on the Clarion side. Are you sure it is stdcall
which is what your C# uses.