我想從我的C#應用程序中用C編寫的DLL調用方法。下面是我實現的呼叫:從C#調用C DLL函數 - 將字符參數轉換爲字符串
- > C法簽名:(從第三部分公司)
Int16 SSEXPORT SS_Initialize(Uint16 ServerIds[], Uint16 ServerQty, const char PTR *Binding, const char PTR *LogPath, Uint16 LogDays, Int16 LogLevel, Uint16 MaxThreads, Uint16 ThreadTTL, Int16 (CALLBACK *ProcessMessage)(Uint16, const char PTR *, Uint32, char PTR **, Uint32 PTR *, Int16 PTR *));
- > C型定義:
#ifndef _CSISERVERTYPES_ #define _CSISERVERTYPES_ #if defined(OS_NT) #define CALLBACK __stdcall #define SSEXPORT __stdcall #define PTR typedef char Int8; typedef unsigned char Uint8; typedef short Int16; typedef unsigned short Uint16; typedef long Int32; typedef unsigned long Uint32; typedef unsigned char Byte; typedef unsigned short Word; typedef unsigned long Dword; typedef short Bool; #endif typedef Int16 (CALLBACK *PM_Function) (Uint16,const char PTR *,Uint32,char PTR **,Uint32 PTR *,Int16 PTR *); #define SS_OK 0 #define SS_NOT_INIT -1 #define SS_PROC_ERR -2 #define SS_ERR_TCP_SRV -3 #define SS_ERR_OUT_MEM -4 #ifndef NULL #define NULL 0 #endif #endif
- > C#DLL方法聲明:
[DllImport("CSITCPServer.dll", SetLastError = true)]
static extern Int16 SS_Initialize(
UInt16[] ServerIds,
UInt16 ServerQty,
ref string Binding,
ref string LogPath,
UInt16 LogDays,
Int16 LogLevel,
UInt16 MaxThreads,
UInt16 ThreadTTL,
ProcessMessageCallback callback);
方法調用:
public static void Call_SS_Initialize()
{
Int16 ret;
UInt16[] serverIds = new UInt16[] { 2020, 2021 };
string binding = "";
string logPath = "";
try
{
ret = SS_Initialize(
serverIds,
Convert.ToUInt16(serverIds.ToList().Count),
ref binding,
ref logPath,
10,
0,
256,
300,
ProcessMessage);
Console.WriteLine("Call_SS_Initialize() -> Result of SS_Initialize: {0}", ret.ToString());
}
catch (Exception ex)
{
Int32 err = Marshal.GetLastWin32Error();
throw new Win32Exception(err);
//throw;
}
}
然後我得到Win32Exception:1008 - 試圖引用一個令牌不存在
我知道,這個問題必須在非託管(C)之間的CHAR到字符串轉換和託管(C#)代碼。如果我修改綁定或LogPath參數到類型SByte,它不會給出任何錯誤。但由於該方法需要一個文本(字符串),我不知道如何將文本傳遞給該方法,因爲它期望一個SByte變量...
我知道我可能不得不使用某些東西像MarshalAs,但我已經嘗試了幾個選項,並沒有取得任何成功。
有人可以告訴我我做錯了什麼?
非常感謝!
這裏是回調的定義:
public delegate Int16 ProcessMessageCallback(
UInt16 ServerId,
[MarshalAs(UnmanagedType.LPStr)] ref string RequestMsg,
UInt32 RequestSize,
[MarshalAs(UnmanagedType.LPStr)] ref string ResponseMsg,
ref UInt32 ResponseSize,
ref Int16 AppErrCode);
的事情是,在C DLL方法需要一個 「REF」 參數。撥打SS_Initialize將執行附加到ProcessMessage回撥函數。在這個函數中,我需要能夠得到SS_Initialize修改的參數(REF)...
可否請你建議,你認爲怎樣的代碼應該是結構化?
謝謝!