델파이 dll을 c#에서 사용할 경우 마샬링에 대해서

델파이로 만들어진 dll을 c#에서 사용하게 되었습니다.
해당 dll에서 다른 함수들은 잘 사용을 하고 있지만 하나 사용하지 못하고 있는 것이 있습니다.

dll 함수의 형태는 이러 합니다.

function GetData: array[0…47, 0…127]; stdcall;

이름은 GetData라는 메서드이고 매개변수는 없고 반환 형은 word 2차원 배열 입니다. word는 c#에서는 부호 없는 정수형 표현으로 ushort라는 것을 확인했습니다.

[DllImport(“DELPHIDLL.dll”, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = “GetData”)]
[return : MarshalAs(UnmanagedType.SafeArray)]
public static unsafe extern ushort[,] GetData();

그래서 c#에서 이렇게 작성을 하고 해당 메서드를 불러오면 프로그램이 그냥 닫히네요.
델파이에서 2차월 배열을 받아올 때 저 마샬링이 맞는지도 모르겠고 델파이와 더 맞춰줘야 되는게 있을까요???

델파이 dll은 제가 만든게 아니다보니 제가 수정은 불가합니다.

고수님들 제발 도와주세요ㅠㅠ

좋아요 2

성태님 홈페이지에도 질문 글 올리신 분 맞지 않나 싶은데요.
어쨋든 그 정도로 잘 안될 경우에는 먼저 C++에서 호출이 되는지 확인을 해 보시고
그 다음에 그 코드를 이용해서 C++/CLI로 감싸보는 것도 방법이지 싶네요.
만약 C++에서도 비슷한 문제가 나온다면 호출 자체가 안된다는 거니까요.

좋아요 3

성태님 홈페이지 올린 질문자 맞아요 ㅠㅠ
그때 이것저것 확인해 보고 하니 그때 질문은 c#에서 주소값을 매개변수로 넘겨서 처리하는 거였는데 넘어가긴 했거든요. 다만… dll이 이상했던 건지 돌아온 주소의 값이 이상했지만요.

이건 조금 다른 내용인데 말씀하신 데로 일단 c++로 해봐야 겠네요. 댓글 감사합니다.

좋아요 2

델파이를 경험한적이 없어서 답변이 부적활할 수 있다는 점은 참고 바랄께요.

먼저, 다차원배열의 마샬링은 안되는 것으로 알고 있어요. 대신 1차원 배열로 받고 처리하시면 됩니다. 그리고 SafeArray가 아닌 이상 [MarshalAs(UnmanagedType.ByValArray, SizeConst = xxxx)] 형태의 SizeConst를 지정하셔야 할꺼에요.

좋아요 3

:thinking: 델파이에서 만든 DLL이 일단 StdCall 콜링 컨벤션을 쓰지 않을 수도 있을 것 같은데요, 이러면 GetData라는 함수를 다른 델파이 코드에서 사용할 수 있도록 Stub Delphi 코드가 있어야 닷넷이 아니라 다른 곳에서도 API를 쓸 수 있기 때문에 일단 관련 코드가 있는지 다시 한 번 꼭 찾아보셨으면 좋겠습니다. 즉, 델파이 코드로 된 DLL 호출 샘플이 있는지 꼭 한 번 보시라는 말씀을 드립니다.

만약 그런 파일이 없다면, Trial and Error를 반복하면서 런타임 안정성 저하 MDA가 닷넷 디버거 쪽에서 나오지 않을 때까지 충분히 테스트를 반복하면서 정확한 signature를 잡으셔야만 합니다. 이 부분을 제대로 마치지 않고 프로덕션에 애플리케이션을 배포하면 메모리 누수나 여러 문제가 발생해서 품질이 크게 떨어질 수 있습니다.

참고 자료: Jun`s Story :: [Delphi] DLL 호출 규칙(Calling Convention) 테스트용 DLL 및 Source - Language/Delphi -

좋아요 4