我試圖爲P調用函數/從C++/Win32的DLL調用一個函數,但每當我把它叫做我得到以下錯誤:獲取AccessViolationException當P /從C++/Win32的DLL
System.AccessViolationException occurred
HResult=-2147467261
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=mscorlib
StackTrace:
at System.StubHelpers.MngdNativeArrayMarshaler.ConvertContentsToManaged(IntPtr pMarshalState, Object& pManagedHome, IntPtr pNativeHome)
InnerException: (Nothing)
隨着表示(使用非託管調試)調用堆棧:
ZaRCon.exe!ZaRCon.Huffman.Encode(Byte() Array) Line 50 + 0x15 bytes
這似乎是一個問題與參數(由於MngdNativeArrayMarshaler.ConvertContentsToManaged()
呼叫)。我試圖改變參數的聲明,但沒有成功。一開始我遇到了麻煩,所以在對其他Stack Overflow問題進行了一些研究之後,我提出了下面的問題。
C++函數聲明:
void __declspec(dllexport) HUFFMAN_Encode(unsigned char *in, unsigned char *out, int inlen, int *outlen);
VB.NET的P/Invoke:
<DllImport("HuffmanNative.dll", CallingConvention:=CallingConvention.Cdecl, CharSet:=CharSet.Ansi)> _
Private Shared Sub HUFFMAN_Encode(<MarshalAs(UnmanagedType.LPArray)> [in] As Byte(), _
<MarshalAs(UnmanagedType.LPArray)> ByRef [out] As Byte(), _
ByVal inlen As Integer, ByRef outlen As Integer)
End Sub
我怎麼稱呼它:
Public Shared Function Encode(ByVal Array As Byte()) As Byte()
Dim Output As Byte() = New Byte(4096 - 1) {}
Dim OutputLength As Integer = 0
HUFFMAN_Encode(Array, Output, Array.Length, OutputLength) 'The error occurs on this line.
Return Output
End Function
C++函數用於編碼使用霍夫曼算法的特殊版本通過網絡發送的數據。
我不確定是否在調用函數的時候拋出錯誤......在C#中創建了一個測試版本後(它給了我各種非常不同的結果),我可以在源碼中獲得一行代碼,但是我不知道這是否是使用VB.NET時拋出了同樣的錯誤:
void HUFFMAN_Encode(unsigned char *in, unsigned char *out, int inlen, int *outlen)
{
int i,j,bitat;
unsigned int t;
bitat=0;
for (i=0;i<inlen;i++)
{
t=HuffLookup[in[i]].bits;
for (j=0;j<HuffLookup[in[i]].len;j++)
{
huffman_PutBit(out+1,bitat+HuffLookup[in[i]].len-j-1,t&1);
t>>=1;
}
bitat+=HuffLookup[in[i]].len;
}
*outlen=1+(bitat+7)/8;
*out=8*((*outlen)-1)-bitat; //<-- The error I got when using C# was thrown here.
if(*outlen >= inlen+1)
{
*out=0xff;
memcpy(out+1,in,inlen);
*outlen=inlen+1;
}
}
所以我的猜測是,我發送給該函數的字節數組未正確轉換爲原生unsigned char
指針數組。但是如果是這樣的話,P/Invoke應該如何執行?如果情況並非如此,那麼問題可能是什麼?
哇,它的工作原理!我以爲我已經嘗試了第二個參數'ByVal'。非常感謝! –