C++ dll을 C#에서 사용시 Callback 함수 어떻게 구현 하나요?

C++ dll에서 callback 함수를 요구하고, callback이 발생하면 C#의 함수를 실행해야 합니다
중간에 CLR로 작성했는데 오류가 없어서 잘된 줄 알았는데 C#쪽 콜백 함수 호출이 안되네요.

각각 따로는 확인했는데요
C++ 단에서 콜백이 호출되는건 확인했고요.
CLR에서 C# 함수를 실행했을때 실행되는 것도 확인했습니다.

CLR에서 C++과 C#을 어떤게 연결해야 하는건지를 잘 모르겠습니다.

////// C++/CLR
public delegate void DELE_ERROR(int32_t errorCode, String^ errorText);
public delegate void DELE_SUCCESS(int32_t id, String^ keyword, int32_t length);

CTest::Init(DELE_ERROR^ deleError, DELE_SUCCESS^ deleSuccess)
{

//     void (*onError)     (int32_t errorCode, char* errorText);
pVaListener->onError = deleError;   // 요부분을 어떻게 써줘야 할까요?
//    void (*onSuccess)  (int32_t id, char* keyword, int32_t length);
pVaListener->onSuccess = deleSuccess;   // 요부분을 어떻게 써줘야 할까요?

}

////// C#

    test.Init(OnError, OnSuccess);
    ...

    public static void OnError(Int32 errCode, String errText)
    {
        Console.WriteLine($"!!!!!!!!!!!!!!!!!!! OnError {errText}");
    }
    public static void OnSuccess(Int32 id, String keyword, Int32 length)
    {
        Console.WriteLine($"############## OnSuccess {keyword}, {length}");
    }

어느 부분이 잘못 됐을까요?

질문하신 내용에 대한 구현을 해본적은 없지만 관련 문서를 찾아보았습니다.

Marshaling a Delegate as a Callback Method | Microsoft Docs

이 글은 .Net의 Interop Marshaling에서 콜백함수를 Unmanaged (c++)로 전달하는 방법에 대해 설명합니다.

1개의 좋아요

제가 C++/CLR 관련 경험이 없어서 적극적으로 답변을 못달고 있습니다.
그래서 검색한 내용을 첨부해봅니다.

C#과 C++ 연동 (github.com)

두번째로, GC이후 문제가 될 수 있는데, 아래의 글을 참고하시면 됩니다.

.NET Framework: 133. CallbackOnCollectedDelegate was detected (sysnet.pe.kr)

1개의 좋아요

코드를 따라해보다가 일단 맞춰야 하지 않을까 싶은 부분들 몇 가지만 말씀드려보면…

  • int32_t 대신 Managed C++/CLI인 경우에는 System::Int32 타입으로 받아야 하지 않나 싶습니다.
  • pVAListener에서 onError나 onSuccess를 부르려고 하시는 것 같은데, pVAListener가 Managed Type인지 Unmanaged Type인지에 따라 대리자 참조 (CLR에서는 포인터 개념이 없고 참조 개념을 씁니다.)를 어떻게 받아서 활용할 것인지가 갈릴 것 같습니다. 마샬링 관련된 내용을 좀 보셔야할 것 같네요.

이 정도가 일단 눈에 띕니다. 시간나면 코드를 좀 더 흉내내어보고 비슷하게 돌아가는 샘플을 한 번 만들어보면 좋을 것 같네요. 어느 정도 샘플이 그려지면 올려보겠습니다.

1개의 좋아요

직접적인 관련은 없고, 뭐 이런것도 있습니다. 중간 브릿지 역할을 자동으로 수행한다고 합니다.

Home :: Scapix Language Bridge

1개의 좋아요

얼마나 비슷한 상황인지는 모르겠지만, 일단 보여주신 샘플 코드 조각을 이용해서 VC++ 2019 기준으로 C++/CLR과 C#을 같이 사용하는 샘플 코드를 좀 만들어보았습니다.

GIST: C++/CLI and C# Interop Sample - For Complete Source Code, Go to https://github.com/level120/CsharpCppSample · GitHub
전체 소스: Microsoft OneDrive - Access files anywhere. Create docs with free Office Online.

일단 이 샘플 기준으로는 호출은 잘 되는 것 같습니다.

3개의 좋아요

링크에 있는 예제는 dll을 직접 호출해서 사용했네요.
저는 상황이 좀 다른데… 중간에 C++/CLR을 구현해서 사용중입니다.
답변 감사드려요

저도 첫번째 주신 링크를 참고해서 작성한 소스인데 왜 안되는 건지 모르겠네요
검색까지 해서 알려주시고…감사합니다.

전체 소스 받아서 살펴봤습니다.

약간 차이가 있는데…
프로젝트가 하나 더 있습니다.
pVaListener가 C++ dll 프로젝트에 있고 dll에서 콜백을 호출하고 있습니다.
(pVaListener는 unmanaged입니다)
정성어린 답글 감사드립니다.

남정현님 코드를 조금 수정해서 c++에서 콜백을 호출하도록 해봤습니다.
일단 수정한 샘플로 동작은 잘 이뤄지는 것 같습니다.

(파일첨부가 안되어 일단 개인 repo로 올렸습니다만 남정현님 코드 베이스라서 혹시라도 불편하시면 지우거나 옮기겠습니다)

2개의 좋아요

훌륭합니다. 다만 소스 코드가 어디서 온 것인지 출처를 README.md에 기재해주신다면 더 좋을 것 같습니다. :+1: (처음 쓴 에모지는 잘못 쓴것입니다. :pray: )

1개의 좋아요

제가 앞서 올렸던 Gist 설명에 공유해주신 리포지터리 주소를 백링크로 걸었습니다. image

2개의 좋아요