2016-07-15 24 views
0

我得到了這樣的C-DLL中定義的函數:爲什麼在將此結構從C#調用/封送到C-DLL時此字符串爲空?

int AcquireArchive (char* archiveName, Password* password) 

的結構密碼在DLL中定義爲:

typedef struct password { 
unsigned char* pPwd; 
unsigned long length; 
} Password; 

什麼我做的是試圖總結這個功能C#中使用:

[DllImport("name.dll", CharSet = CharSet.Ansi, EntryPoint = "[email protected]", 
CallingConvention = CallingConvention.StdCall)] 
public static extern int AcquireArchive(
[MarshalAs(UnmanagedType.LPStr)] string archiveName, 
ref Password password 
); 

和:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public struct Password 
{ 
    public string pwd; 
    public ulong length; 
} 

我通過調用此函數:

Password password; 
password.pwd = "password"; 
password.length = (ulong)password.pwd.Length; 

int code = AcquireArchive("Archive", ref password); 

現在的問題是,返回的代碼信號無效的密碼,表明(根據文檔)的0 密碼長度是否有可能密碼的值.pwd和/或password.length會在調用/編組過程中丟失?

很遺憾,我無法訪問dll的源代碼。

編輯:字符集現在是ANSI,TYPO 「長度」,除去[UnmanagedType.BStr]

+0

C++代碼是否使用Unicode?因爲'CharSet.Auto'會在WIndows XP或更高版本上如此。 –

+0

它不是一個UnmanagedType.BStr,刪除它。結構上的CharSet.Auto是錯誤的,你必須使用CharSet.Ansi。 –

+0

我認爲這裏有一個錯誤:password.lenght <-----你應該改正「lenght」 – Mimouni

回答

1

至少一個問題,我看到:
在C代碼(長度爲32位或64位取決於到DLL ):

typedef struct { 
    unsigned char* pPwd; 
    unsigned long length; 
} Password; 

,並在您的C#代碼(長度爲64位):

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
public struct Password 
{ 
    public string pwd; 
    public ulong length; 
} 

如果是64位,這是確定。 但如果是32位的,你應該改變你的C#ulonguint這樣的:

public struct Password 
{ 
    public string pwd; 
    public uint length; 
} 

我希望這有助於。

+1

確實是這個問題!非常感謝! –

+0

使用InteropServices時是否有任何種類的數據類型兼容性概覽表?這會很好的避免像這樣的錯誤 –

+0

@ sascha-g:對於這種類型兼容性,我恐怕不會。但爲了將託管轉換爲非託管類型,請參閱:https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal(v=vs.100).aspx – 2016-07-18 09:16:07

相關問題