2012-05-16 125 views
3

我目前正在一家IT公司工作。他們使用Clarion, 製作了他們的軟件,並且在那個軟件中他們有一個DLL,它從他們的數據庫重新計算了很多值。我需要從我的C#項目調用這個DLL。我嘗試了一切,沒有它的工作。從C調用Clarion DLL#

我的代碼如下:

public partial class Form1 : Form 
{ 
    [DllImport("EPNORM.dll", EntryPoint = "[email protected]")] 
    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(很長很長,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

你能否提供這個Clarion庫的更多信息?它在我看來,你正在傳遞的參數有問題。 – Dimitris

+0

hey dimitris我更新了我的帖子,其中包含了號角端代碼 – Mrlondon7100

+0

您是否有任何訪問這些函數的C/C++示例? –

回答

2

第一個參數是一個指向空終止字符串的指針。你不能只傳遞一個隨機的Int64值。所以,你的PInvoke應該是這樣的:

[DllImport("EPNORM.dll", EntryPoint = "[email protected]")] 
public static extern void MyRecalcualate(string myPtr, int myInt, byte myByte); 

我認爲,第二個參數,克拉里昂LONG,是一個32位整數。所以在C#端的int。更重要的是,你需要仔細檢查克拉里昂方面的通話大會。你確定這是你的C#使用的stdcall

+0

嘿我上傳了一張參數圖片,因爲第一個參數是一個字符串值,但該參數需要發送得很長。所以不知何故,他們將字符串編碼爲內存地址並使用該參數。 – Mrlondon7100

+1

我相信你需要按照我在答案中所說的方式去做。我的猜測是Clarion是32位,LONG是32位整數。這與32位指針的大小相同。如果這一切都是真的,那麼第二個參數需要在P/invoke中輸入爲「int」而不是「long」。 –

+0

正如我剛剛在[我最近的問題在這裏](http://stackoverflow.com/questions/13130365/convert-a-clarion-procedure-declaration-to-c-sharp-dllimport),克拉里昂'長'是一個32位有符號整數,映射到C#System.Int32('int')。 – DanM7