2013-08-22 198 views
0

任何人都知道我如何修復此錯誤?從託管代碼調用非託管代碼

錯誤:

A call to PInvoke function has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

我使用P/Invoke從託管代碼調用本機代碼。本地代碼正在通過動態鏈接庫導入。

步驟是

  1. 定位的.dll含有這些功能。
  2. 加載的.dll到存儲器
  3. 定位的函數的地址在存儲器
  4. 轉化對象的此內存中表示的數據格式(編組)

DLL具有聲明的功能

long __stdcall Connect (long,long,long,long,long,long,long,long);` 

在我的申請中,我創建了一個代理

[UnmanagedFunctionPointer(CallingConvention.StdCall)] 
private delegate long delConnect(long a, long b, long c, long d, long e, long f, long g, long h);` 

然後創建了一個類裝載DLL和在存儲器中定位的功能地址

`靜態類NativeMethods { [的DllImport( 「KERNEL32.DLL」)] 公共靜態外部的IntPtr的LoadLibrary(串dllToLoad);

[DllImport("kernel32.dll")] 
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); 


    [DllImport("kernel32.dll")] 
    public static extern bool FreeLibrary(IntPtr hModule); 
}` 

現在,當我試圖使用的功能,然後我得到錯誤

IntPtr pDll = NativeMethods.LoadLibrary("serial.dll"); 
IntPtr pAddressOfFunctionToCall = NativeMethods.GetProcAddress(pDll, "[email protected]"); 
delConnect connect = (delConnect)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall,typeof(delConnect)); 
long check = connect(1, 0, 12, 9600, 0, 0, 8, 0); 
bool result = NativeMethods.FreeLibrary(pDll);` 

我已經在GetProcAddress的方法的函數名參數使用「_Connect @ 32」,而不是「連接」,因爲的名字搗毀。

當我調試我在行得到這個錯誤含聲明

long check = connect(1, 0, 12, 9600, 0, 0, 8, 0);

回答

1

的C/C++ long是在Windows 32位,所以在.netint。試着改變它(在Unix上它更像是一個IntPtr

[UnmanagedFunctionPointer(CallingConvention.StdCall)] 
private delegate int delConnect(int a, int b, int c, int d, int e, int f, int g, int h); 

也許不是StdCall嘗試Cdecl

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 

對於Windows API的DllImport你應該使用

[DllImport("kernel32.dll", CharSet=CharSet.Auto)] 

因此,如果可能的話,.NET使用Unicode變體,而不是Ansi變體。

+0

由於它的工作。 –

0

你有沒有理由使用LoadLibrary()而不是直接使用PInvoking?

,如果你試試這個,而不是會發生什麼:

[DllImport("serial.dll", EntryPoint = "[email protected]", CallingConvention = CallingConvention.StdCall)] 
static extern int DelConnect(int a, int b, int c, int d, int e, int f, int g, int h); 

(注C#INT == C++長,正常)