我需要調用那些DLL用C++編寫的C#控制檯應用程序的功能。我編組並在C#中編寫了相同的數據類型。但無論如何,我得到的錯誤。哪裏有問題?無法調用用C語言編寫的DLL函數++從C#
這裏是DLL的功能
extern "C" {
SAMPLENATIVEDLL_API int GetCardInfoEx(INT64 Card, DWORD Restaurant, DWORD UnitNo, TCardInfoEx* Info, char* InpBuf, DWORD InpLen, WORD InpKind, char* OutBuf, DWORD OutLen, WORD OutKind) {
int res = getCardInfoEx(Card, Info, UnitNo);
return res;
}
}代碼
這裏是TCardInfoEx結構代碼
#pragma pack(1)
typedef struct TCardInfoEx {
WORD Size;
BYTE Deleted;
BYTE Seize;
BYTE StopDate;
BYTE Holy;
BYTE Manager;
BYTE Blocked;
CHAR WhyLock[256];
CHAR Holder[40];
INT64 UserID;
DWORD CardAccountNumber;
DWORD TypeOfDefaulter;
WORD Bonus;
WORD Discount;
INT64 Summa;
INT64 AvailableSumma;
INT64 SummaOnCardAccount2;
INT64 SummaOnCardAccount3;
INT64 SummaOnCardAccount4;
INT64 SummaOnCardAccount5;
INT64 SummaOnCardAccount6;
INT64 SummaOnCardAccount7;
INT64 SummaOnCardAccount8;
CHAR OtherCardInformation[256];
CHAR OtherCardInformation1[256];
CHAR OtherCardInformation2[256];
};
以下是我在C#中做結構
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TCardInfoEx
{
ushort Size;
byte Deleted;
byte Seize;
byte StopDate;
byte Holy;
byte Manager;
byte Blocked;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
String WhyLock;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
String Holder;
Int64 UserID;
uint CardAccountNumber;
uint TypeOfDefaulter;
ushort Bonus;
ushort Discount;
Int64 Summa;
Int64 AvailableSumma;
Int64 SummaOnCardAccount2;
Int64 SummaOnCardAccount3;
Int64 SummaOnCardAccount4;
Int64 SummaOnCardAccount5;
Int64 SummaOnCardAccount6;
Int64 SummaOnCardAccount7;
Int64 SummaOnCardAccount8;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
String OtherCardInformation;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
String OtherCardInformation1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
String OtherCardInformation2;
};
這裏是c頌歌,我調用的方法(函數)
class Program
{
[DllImport("SampleNativeDLL.dll", CharSet = CharSet.Unicode)]
public static extern int GetCardInfoEx(Int64 Card, uint Restaurant, uint UnitNo, TCardInfoEx Info, String InpBuf, uint InpLen, ushort InpKind, String OutBuf, uint OutLen, ushort OutKind);
static void Main(string[] args)
{
TCardInfoEx tc = new TCardInfoEx();
GetCardInfoEx(1248000259045, 1, 1, tc, "", 0, 1, "", 1, 1);
}
}
而且我得到以下錯誤: 託管調試助手「PInvokeStackImbalance」已檢測到一個問題,「\ BIN \調試\ FCFake.vshost.exe」。
其他信息:對PInvoke的函數調用「計劃:: GetCardInfoEx」有不平衡的堆棧。這很可能是因爲託管的PInvoke簽名與非託管目標籤名不匹配。檢查PInvoke簽名的調用約定和參數是否與目標非託管簽名相匹配。
如何解決這個問題?
UPD:我編輯根據德克的回答TCardInfoEx結構。可惜的是,它並沒有幫助我
嘗試爲您的字符串成員使用'[MarshalAs(UnmanagedType.ByValTStr,SizeConst = ????)]'屬性,或者將它們不作爲字符串編組,而是作爲Byte數組。 – 2014-09-02 07:14:42
我不確定,但'字符串WhyLock'字符串持有人'不匹配'字符WhyLock [256]'和'字符持有人[40]'。你認爲String如何知道即256字節長? – lifeOfPI 2014-09-02 07:15:00
包裝也是錯的。並且p/invoke需要通過ref傳遞結構。 – 2014-09-02 07:34:13