C#관리되지 않는 DLL 호출--[1] 기본 단계
3924 단어 c#기초
위탁 관리 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;
}
}