인디노트

C# - DLL 인수 전달 코딩 방법 본문

소스 팁/C, C++, C#

C# - DLL 인수 전달 코딩 방법

인디개발자 2021. 9. 18. 20:54

DLL 의 함수를 C# 에서 연결하는 방법

DLL 코드

C 코드

__declspec(dllexport) void __cdecl Function1(void)
{
    
}
__declspec(dllexport) int __cdecl Function2(void)
{
    return 100;
}
__declspec(dllexport) char* __cdecl Function3(void)
{
    return "Function3";
}
__declspec(dllexport) void __cdecl Function4(char *from, char **to)
{
    memcpy(*to, from, (int)strlen(from)+1);
}

 

H 코드

#ifdef _cplusplus
extern "C" {
#endif // _cplusplus

__declspec(dllexport) void __cdecl Function1(void);
__declspec(dllexport) int __cdecl Function2(void);
__declspec(dllexport) char* __cdecl Function3(void);
__declspec(dllexport) void __cdecl Function4(char *from, char **to);

#ifdef _cplusplus
}
#endif

위의 코드로 functions.dll 을 만들었다고 하면 다음과 같이 C# 에서 호출할 수 있다.

DllFunctions.cs

public class DllFunctions
{        
    [DllImport("functions.dll", CallingConvention = CallingConvention.Cdecl)]
    extern internal static void Function1();

    [DllImport("functions.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern internal int Function2();

    [DllImport("functions.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern internal IntPtr Function3();

    [DllImport("functions.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void Function4(string from, ref string to);
    
    public DllFunctions()
    {
        // 아무것도 주거나 받거나 하지 않고 수행만 하는 함수
        Function1();
        
        // int 값을 리턴하는 함수 (C 에서 int 를 리턴)
        int n = Functions2();
        
        // string 값을 리턴하는 함수 (C 에서 char * 를 리턴)
        IntPtr pstr = Function3();
        string str = PtrToStringUtf8(pstr); // IntPtr 를 가져와서 string 으로 변환
                
        // string 을 인수로 주고 string 를 인수로 받아오는 함수
        string from = "This is a from string";
        string to = new string((char)0x00, 50);
        Function4(from, ref to)
    }
    
    private string PtrToStringUtf8(IntPtr ptr) // aPtr is nul-terminated
    {
        if (ptr == IntPtr.Zero)
            return "";
        int len = 0;
        while (System.Runtime.InteropServices.Marshal.ReadByte(ptr, len) != 0)
            len++;
        if (len == 0)
            return "";
        byte[] array = new byte[len];
        System.Runtime.InteropServices.Marshal.Copy(ptr, array, 0, len);
        return System.Text.Encoding.UTF8.GetString(array);
    }
}

이와같이 C# 에서 C 함수를 호출하여 인수를 전달하는 방법에 다양한 변수 및 포인터 그리고 구조체 및 클래스 (예; StringBuilder) 등도 전달 할 수 있다.

 

다음의 문서를 참고하면 좋을 듯 하다.

https://indienote.tistory.com/649

 

C# C++ DLL

https://secmem.tistory.com/598 [6기 강북 이보희] C++로 만든 DLL을 C#에서 사용하기  안녕하세요. 강북멤버십 22-1기 이보희입니다. C++로 만든 dll을 C#에서 사용하는 방법에 대해 알아보겠습니다. 1. C# 프..

indienote.tistory.com

 

반응형
Comments