2010-03-19 1 views
0

안전하지 않은 콜백의 메시지를 관리되는 코드로 전달하는 간단한 예제가 있습니까?C#. 안전하지 않은 콜백에서 관리되는 코드로 메시지를 전달하는 방법

구조체에있는 일부 메시지를받는 독점적 인 dll을 가지고 있으며 모두 콜백 함수를 사용하고 있습니다.

사용 예는 다음과 같습니다.하지만 안전하지 않은 코드도 호출합니다. 모든 관리 코드 인 애플리케이션에 메시지를 전달하고 싶습니다.

* P. 나는 interop 또는 unsafe 코드에 대한 경험이 없습니다. 나는 C++ 8 년 전에 개발 했었지만 그 악몽 같은시기에는 거의 기억하지 못했습니다 :)

P.P. 응용 프로그램이 지옥으로로드, 원래의 devs 내가 가장 효율적인 솔루션이 필요합니다 ..이 초당 2mil 메시지를 처리 ​​주장한다. *

static unsafe int OnCoreCallback(IntPtr pSys, IntPtr pMsg) 
{ 
    // Alias structure pointers to the pointers passed in. 
    CoreSystem* pCoreSys = (CoreSystem*)pSys; 
    CoreMessage* pCoreMsg = (CoreMessage*)pMsg; 

    // message handler function. 
    if (pCoreMsg->MessageType == Core.MSG_STATUS) 
    OnCoreStatus(pCoreSys, pCoreMsg); 

    // Continue running 
    return (int)Core.CALLBACKRETURN_CONTINUE; 
} 

감사합니다.

+0

관리 코드는 메시지로 무엇을 할 것인가? 어떤 종류의 데이터가 메시지입니까? 문자열? 또는 관리되지 않는/안전하지 않은 코드로 다시 전달 될 포인터는 무엇입니까? 대답은 이런 일에 완전히 달려 있습니다. – snarf

+0

나는 메시지가 관리되지 않는 코드로 돌아 가지 않을 것이라고 확신한다 ... 지금까지 내가 한 일은 - API 샘플의 비 관리 코드를 WPF 앱에 추가하고 각각의 메시지 데이터를 구조체로 랩핑했다. 이미 WPF에서 사용하고 그것을 창으로 다시 밀어 ... 문제는 내가 this.Dispatcher.BeginInvoke (새로운 액션 (() => {OnDataReceived (data);})를 호출 할 때 ... 나는 결코 들어 가지 않는다. OnDataReceived 메서드. 내가 그것에 중단 점을 설정하려고 시도하고 너무 적중 ... 나는 지금 붙어있다 ... MyStruct 및 발송자 작업과 OnDataReceived - 관리되는 스레드에서 호출 할 때 모두 작동 함 –

+0

PS MyStruct가 작음 32 bit struct - 모두 int, uint, long .. 참조 유형이 없습니다. 심지어 문자열이 아닙니다. –

답변

0

마샬 클래스를 사용하여 interop 코드를 처리 할 수 ​​있습니다.

예 :

C: 
void someFunction(int msgId, void* funcCallback) 
{ 
    //do something 
    funcCallback(msgId); //assuming that function signature is "void func(int)" 
} 

C# 
[DllImport("yourDllname.dll")] 
static extern someFunction(int msgId, IntPtr funcCallbackPtr); 

public delegate FunctionCallback(int msgId); 
public FunctionCallback functionCallback; 

public void SomeFunction(int msgId, out FunctionCallback functionCallback) 
{ 
    IntPtr callbackPtr; 
    someFunction(msgId, callbackPtr); 

    functionCallback = Marshal.DelegateToPointer(callbackPtr); 
} 

you can call as: 
SomeFunction(0, (msgIdx) => Console.WriteLine("messageProcessed")); 

내가 바로했다 바랍니다. 나는 그것을 컴파일하려고하지 않았다.