C#에서 C++ DLL사용시 debug, release에 따른 오류 질문

다른 사람이 linux C++에서 사용하던 소스를 dll로 빌드하여 제가 C#에서 사용하려고 합니다.
중간에 CLR 작성하고 해서 어찌 어찌 연결은 했는 실행하려고 하니 dll에 있는 함수 호출에 예외 오류가 발생합니다.
특별한 예외 오류는 아니고 일반 적인 오류라서 힌트가 될만한 내용도 없습니다.
(System.Runtime.InteropServices.SEHException: ‘외부 구성 요소에서 예외를 Throw했습니다.’)
딱히 오류가 날만한 부분도 아니라서 확인하던 중…
release에서만 오류가 나고 debug 에서는 오류가 나지 않는걸 확인했습니다.
(dll과 app단의 debug, release 모드는 맞추었습니다)

궁금한건 이러한(C#에서 C++ DLL을 사용하는) 구성시 빌드 옵션에 추가로 설정해야 하는 옵션 같은게 있는지요?
아니면 dll을 빌드해준 쪽에서 C#에서 사용할 DLL은 먼가 특별한 옵션을 줘서 만들어 주는 옵션이 있는 건지요?

읽어 주셔서 감사합니다.

1개의 좋아요

SEHException 만으로는 무엇이 원인인지 직접 알기는 어려워보이는데요, 혹시 SEHException 안의 ErrorCode 프로퍼티가 어떻게 설정되어 넘어왔는지도 알려주실 수 있을까요? 거기에 원인이 있지 않을까 생각합니다.

SEHException Class (System.Runtime.InteropServices) | Microsoft Docs

참고로 C++에 맞춘 DLL 이라는 컨셉은 따로 없습니다. DLL은 항상 C 언어처럼 함수 단위로만 export를 제공하며, 여기서 벗어나는 케이스는 다음에 해당합니다.

  • 각 컴파일러 제조사마다 C++ 클래스와 각 메서드, 필드를 바인딩할 수 있도록 사전에 정의한 Naming Mangling에 따라 커스터마이징해서 Export한 함수들 (Microsoft의 Visual C++과 Borland의 C++ 컴파일러 등 각각이 규칙이 다릅니다. 일종의 프로토콜로 생각할 수 있고, 이 프로토콜을 리버스 엔지니어링해서 사용할 수 있다면 나름 유용한 부분은 있습니다.)
  • Java 런타임을 위하여 설계된 JNI 메서드
  • 타입라이브러리 및 약속된 몇 가지 함수를 이용하여 COM 인터페이스를 넘겨받는 경우 (순수한 C 언어 Import, Export 만이 아니라 Win32 리소스까지 활용하는 케이스입니다.)
  • 모든 내용이 C++/CLR로 구성되어있어서 그 자체로 닷넷 어셈블리인 경우
  • Windows Metadata 형태로 포장된 라이브러리인 경우

위의 경우를 제외하고는 모두 C 언어 기준으로 함수들이 내보내지고, 바깥에서도 불러서 사용하게 됩니다. 그래서 C 언어 함수 원형에서 어떻게 시그니처를 내보냈는지 정확히 이해하고 맞춰서 DllImportAttribute를 써주셔야 합니다. (이것이 특별한 옵션에 해당하는 부분입니다.)

debug와 release DLL간 차이는 없다는 말씀이지요?

일단은 그렇습니다. 정확한 답을 얻으려면 코드가 어떻게 컴파일되서 나왔는지를 알아야 할 것 같네요.

자세한 상황은 알 수 없어서 정확한 답변은 드릴 수 없지만, DEBUG 매크로 등을 이용해서 이름이나 호출 컨벤션을 조건부로 달리 지정하신게 아니라면 아래 글에서 소개하는 차이점 정도가 있을 수 있습니다.

혹시 가능하시다면 Dependency Walker 같은 유틸리티로 함수 Export가 어떻게 나와있는지 덧붙여주시면 좋을 것 같습니다.

image

예외옵션에서 SEHException 옵션이 켜져있을 때 중단점이 걸리는지 확인해보는 것도 좋을 것 같아요.
위치는 VS - Debug - Windows - Exception Settings 입니다.

dll 파일 복사와 프로젝트 설정에서 경로 지정하는 부분에 어딘가에서 꼬였었나봅니다
파일 한 폴더로 몰아버리고 경로 설정을 단순화했더니 해결되었습니다.

답변 주신 두분 모두 감사합니다.

1개의 좋아요