2012-04-08 3 views
4

에서 설정합니다. 비 관리 C DLL에 대한 C# 바인딩을 쓰고 있습니다.비 관리 C DLL의 공개 필드를 C#

DLL은 여러 데이터를 반환 할 5 훅을 제공 :

typedef void (*t_libpd_printhook)(const char *recv); 

과 같은 필드를 보냅니다 단지를 준 내가 바인딩 코드를 생성하는 Interop Assistant을 사용하고 있었다 지금

EXTERN t_libpd_printhook libpd_printhook; 

, 위임자 정의 :

그래서 어떤 마법의 Interop 함수 호출이 있습니다. DLL에서 t_libpd_printhook 필드를 설정하는 데 사용할 수 있습니까?

+0

아, 하나의 몰랐지만 내가 어떻게 그런 다음에 대리자를 할당 할 것인가? – thalm

+0

네, 제 질문에 대한 정답으로 지금 당신의 대답을 받아 들였습니다. 하지만 내가 사용하는 dll이 오픈 소스이기 때문에 아마 usr이 제안한 것처럼 setter 메소드를 추가 할 것입니다. http://stackoverflow.com/questions/2167895/howto-implement-callback-interface-from-unmanaged-dll-to-net-app – thalm

+0

흥미로운 질문을 내가 세터가 있음을 동의 : 나는이 도움이 될 것으로 네이티브 코드를 컴파일하는 경우 올바른 솔루션입니다. –

답변

4

LoadLibraryGetProcAddress을 사용하여 내 보낸 libpd_printhook 변수에 대한 포인터를 얻을 수 있습니다. 그런 다음 Marshal.WriteIntPtrMarshal.GetFunctionPointerForDelegate을 사용하여 대리인을 할당 할 수 있습니다.

[DllImport("kernel32", SetLastError=true, CharSet=CharSet.Unicode)] 
static extern IntPtr LoadLibrary(string lpFileName); 

[DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, 
    SetLastError=true)] 
static extern IntPtr GetProcAddress(IntPtr hModule, string procName); 

[DllImport("kernel32.dll", SetLastError=true)] 
static extern bool FreeLibrary(IntPtr hModule); 

..... 

IntPtr lib = LoadLibrary(@"mydll.dll"); 
IntPtr plibpd_printhook = GetProcAddress(lib, "libpd_printhook"); 
Marshal.WriteIntPtr(plibpd_printhook, 
    Marshal.GetFunctionPointerForDelegate(mydelegate)); 
FreeLibrary(lib); 

간략한 예를 위해 excised 한 오류 검사를 추가 할 수 있습니다. 당신이 관리되지 않는 라이브러리의 컨트롤에있는 경우

지금, 나는 여전히이 함수 포인터에 쓰기 캡슐화하는 기능을 추가하는 것이 좋습니다 것입니다. 그게 나에게 더 좋은 인터페이스 같아.

+0

감사합니다, 아주 좋은 예! 나는 두 가지 방법으로 평가할 것이다. 나는 dll 소스를 가지고 있기 때문에 setter 메소드를 작성할 수있다.이 메소드는 작업량이 적고 사용자가 제안한 것처럼 더 깔끔한 인터페이스이다. – thalm

3

PInvoke를 내 보낸 변수를 지원하지 않습니다. 델리게이트를 가져 와서 필드에 복사하는 관리되지 않는 함수를 만들어야합니다.

+1

예, 절대적으로 진실입니다 – pylover

+1

좋아요, 그래서 C에서 세트 메소드를 추가해야합니다 ... 감사합니다! – thalm

관련 문제