C#관리되지 않는 DLL 호출--[1] 기본 단계

3924 단어 c#기초
호스팅된 DLL과 비호스팅된 DLL의 차이점은 좁은 의미로 호스팅된 DLL이 Dotnet 환경에서 생성된 DLL 파일이라는 것입니다.관리되지 않는 DLL은 Dotnet 환경에서 생성되지 않습니다.
위탁 관리 DLL 파일은 Dotnet 환경에서 '인용 추가' 방식으로 위탁 관리 DLL 파일을 프로젝트에 직접 추가할 수 있습니다.그런 다음 Using DLL 네임스페이스를 사용하여 해당 DLL 객체를 호출합니다.관리되지 않는 DLL 파일은 Dotnet 환경에서 사용할 때 using system을 도입합니다.Runtime.InteropServices;다시 코드에서 DllImport를 통해 호출됩니다.
 
기능: c#에서 c++로 작성된 DLL을 호출합니다.
실현:delegate 설명 함수로 호출을 의뢰하여 리셋을 하고 바늘을 적용할 수 있습니다.
문제점:
1. getProcAddress가 반환하는 값은 0이며NATIVE DLL에서 내보내는 함수를 가져올 수 없습니다. 호출된 함수 이름과 c++ 프로젝트의 일치 여부를 검사합니다.
2. c++ dll의 함수 이름 보기 VIEWDLL은 dll 함수를 내보낸 이름을 볼 수 있습니다
3. 디버그 도우미 "PINvokeStackImbalance": "PINvoke 함수"**.*+ DLL Test:::Invoke"에 대한 호출로 인해 스택이 비대칭적입니다.관리되는 PINvoke 서명이 관리되지 않는 대상 서명과 일치하지 않기 때문일 수 있습니다.PINvoke 서명의 호출 약정과 파라미터가 관리되지 않는 목표 서명과 일치하는지 확인하십시오.
프로그램은 정확한 결과를 실행하고 되돌릴 수 있지만, 여전히 오류를 보고합니다.
해결 방안은 나의 다른 블로그에 있다https://blog.csdn.net/u012482453/article/details/102894850
 
4. exception 값은 null일 수 없습니다.\r 참조 이름: ptr System.ArgumentNullException은 먼저 c++가 생성한 DLL 경로가 정확한지, 호출한 함수 이름이 정확한지 확인합니다. 그 다음에 dll는 c++ 프로젝트가 생성해야 합니다. 처음에 c# 프로젝트로 dll을 생성했습니다. 이 방식으로 호출할 수 없습니다.
5、System.RuntimeType typeof DeclaringMethod가 유형 System을 유발했습니다.InvalidOperation은 처음에는 typeof()가 잘못 보고했다고 생각했는데, 의뢰 유형이나 전송된 파라미터가 틀렸다고 생각했는데, 나중에 dll이 c# 생성으로 인한 것으로 밝혀졌다.
 
 
C#에서는 먼저 DLL 함수 주소를 위임된 클래스로 변환하는 방법과 패키지된 참조를 정의합니다.https://www.cnblogs.com/zeroone/p/3681379.html
C# C++의 함수를 호출하는 또 다른 방법은delegate로 함수 의뢰를 호출하는 것이다. 이런 방법은 약간 번거롭지만 리셋을 하고 지침을 적용할 수 있다.
C#에서 DLL의 함수 주소를 위임으로 변환하는 클래스를 정의합니다.
public class DLLWrapper
    {
    ///
    /// API LoadLibrary
    ///
    [DllImport("Kernel32")]
    public static extern int LoadLibrary(String funcname);
     
    ///
    /// API GetProcAddress
    ///
    [DllImport("Kernel32")]
    public static extern int GetProcAddress(int handle, String funcname);
     
    ///
    /// API FreeLibrary
    ///
    [DllImport("Kernel32")]
    public static extern int FreeLibrary(int handle);
     
    ///
    ///                , by jingzhongrong
    ///
    ///Get DLL handle by LoadLibrary
    ///Unmanaged function name
    ///ManageR type       
    ///
    public static Delegate GetFunctionAddress(int dllModule, string functionName, Type t)
    {
    int address = GetProcAddress(dllModule, functionName);
    if (address == 0)
    return null;
    else
    return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
    }
     
    ///
    ///        IntPtr          , by jingzhongrong
    ///
    public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t)
    {
    if (address == IntPtr.Zero)
    return null;
    else
    return Marshal.GetDelegateForFunctionPointer(address, t);
    }
     
    ///
    ///        int        ,by jingzhongrong
    ///
    public static Delegate GetDelegateFromIntPtr(int address, Type t)
    {
    if (address == 0)
    return null;
    else
    return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
    }
    }

 
//    DLL    , hModule()        DLL   ,         

    private int hModule()
    {
    int _hModule = DLLWrapper.LoadLibrary(DLLPATH);
    if (_hModule == 0)
    {
    return 0;
    }
    return _hModule;
    }
     
    // delegate    
    delegate void _amDBRInitialize (int mid, ref int errid);


    private void amDBRInitialize()
    {
    try
    {
    _amDBRInitialize amf = (_amDBRInitialize)DLLWrapper.GetFunctionAddress(hModule(), "amDBRInitialize", typeof(_amDBRInitialize));
    amf();
    }
    catch (Exception e)
    {
    throw e;
    }
    }

좋은 웹페이지 즐겨찾기