2013-01-31 80 views
3

我從C#代碼調用C函數時遇到了麻煩。我想添加一些功能給VLC播放器(我們通過vlcdotnet在我們的軟件中使用它),並使用mingw在我的ubuntu 12.10上交叉編譯它。我寫了一個功能,我們稱之爲富:C和C#interop的問題

__declspec(dllexport) void Foo(vlc_object_t* bar); 

現在我想從C#調用它:

[LibVlcFunction("Foo")] 
[UnmanagedFunctionPointer(CallingConvention.StdCall)] 
public delegate void Foo(IntPtr pointer); 
........ 
public LibVlcFunction<Foo> Foo { get; private set; } 
...... 
Foo = new LibVlcFunction<Foo>(myLibVlcCoreDllHandle, VlcVersion); 

而失敗。在LibVlcFunction的內部構造函數中,我們組合了GetProcAddress和GetDelegateForFunctionPointer。 GetProcAddress失敗,並且「函數'Foo'的地址不存在....」但是dumpbin和dep。沃克說這個功能是存在的,她的名字沒有被破壞。我試圖編寫一個加載libvlc.dll的C++應用程序,並獲取指向我的func的指針並且它工作正常。但在C#中它失敗了。我該怎麼辦?有什麼建議麼?

+1

可能有可能在C#端使用DllImport和Extern?我從來沒有從編碼的角度與VLC親自合作過,所以我不知道你是否有理由使用你在這裏使用的屬性,這只是一個想法。 –

+0

僅當Dll與應用程序位於同一文件夾中時,DllImport纔有效。我們需要它們在不同的文件夾中,所以我們使用GetProcAddress/GetDelegateForFunctionPointer組合。 – Filippok

+0

明白了,對不起,這只是我個人的經歷而引起的最初想法。 –

回答

0

儘量不要使用STDCALL,轉而使用CDECL,像這樣:

extern "C" __declspec(dllexport) void Foo(vlc_object_t* bar); 

你的平臺調用調用,想這樣:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Runtime.CompilerServices; 

public class libvlc 
{ 
    [DllImport("the-vlc.dll", EntryPoint = "Foo")] 
    extern public static void Foo(IntPtr bar); 
} 

你會把vlc_object_t *爲不透明的句柄。你只是通過它們。這假定vlc_object_t在VLC共享庫中(即在DLL中)被分配和釋放。