c# 플랫폼에서 DLL에서 실행되는 관리되지 않는 함수 호출
7461 단어 dll
이 문서에서는 C#에서 관리되지 않는 DLL 함수를 호출하는 방법에 대해 설명합니다.이 강좌에서 논의한 속성은 이 함수를 호출하여 데이터 형식을 정확하게 봉인할 수 있도록 합니다.
C# 코드에는 관리되지 않는 코드를 직접 호출할 수 있는 두 가지 방법이 있습니다.
이 문서는 다음 항목으로 구성되어 있습니다.
1. C#에서 DLL 직접 내보내기 호출
2. 기본 봉송 처리와 비 트랜잭션 방법의 매개 변수에 사용자 정의 봉송 처리를 지정합니다
3. 사용자 정의 구조에 사용자 정의 봉인 처리 지정하기
4. 등록 콜백 방법
1. C#에서 DLL 내보내기 직접 호출
DLL에서 내보낸 방법을 선언하려면 다음과 같이 하십시오.
예제 1
이 예제에서는 호출
msvcrt.dll
의 puts
를 통해 DllImport 속성을 사용하여 메시지를 출력하는 방법을 보여 줍니다.// PInvokeTest.cs
using System;
using System.Runtime.InteropServices;
class PlatformInvokeTest
{
[DllImport("msvcrt.dll")]
public static extern int puts(string c);
[DllImport("msvcrt.dll")]
internal static extern int _flushall();
public static void Main()
{
puts("Test");
_flushall();
}
}
출력
Test
코드 토론
앞의 예제에서는 관리되지 않는 DLL에서 구현된 C# 메소드를 설명하기 위한 최소 요구 사항을 보여 줍니다.
PlatformInvokeTest.puts
방법은 static와 extern 수식자로 설명하고 DllImport 속성을 가지며 이 속성은 기본 이름puts
을 사용하여 컴파일러에 알립니다 msvcrt.dll
.C# 메서드에 다른 이름putstring
을 사용하려면 다음과 같이 DllImport 속성에 EntryPoint 옵션을 사용해야 합니다.[DllImport("msvcrt.dll", EntryPoint="puts")]
2. 기본 봉송 처리와 비 위탁 관리 방법의 매개 변수에 사용자 정의 봉송 처리를 지정합니다
C# 코드에서 관리되지 않는 함수를 호출할 때 공용 언어 라이브러리는 매개 변수와 반환 값을 봉인해야 합니다.
하나하나에 대해.NET Framework 유형에는 기본적으로 관리되지 않는 유형이 있으며, 공용 언어 실행 라이브러리에서는 이 관리되지 않는 유형을 사용하여 관리되지 않는 함수 호출에서 데이터를 봉인합니다.예를 들어, C# 문자열 값의 기본 봉인 처리는 LPTSTR(TCHAR 문자 버퍼에 대한 포인터) 유형으로 봉인됩니다.관리되지 않는 함수의 C# 선언에서 MarshalAs 속성을 사용하여 기본 봉인 처리를 다시 쓸 수 있습니다.
예제 2
이 예제에서는 DllImport 속성을 사용하여 문자열을 내보냅니다.MarshalAs 속성을 사용하여 함수 매개 변수의 기본 봉인 처리를 다시 쓰는 방법도 보여 줍니다.
// Marshal.cs
using System;
using System.Runtime.InteropServices;
class PlatformInvokeTest
{
[DllImport("msvcrt.dll")]
public static extern int puts(
[MarshalAs(UnmanagedType.LPStr)]
string m);
[DllImport("msvcrt.dll")]
internal static extern int _flushall();
public static void Main()
{
puts("Hello World!");
_flushall();
}
}
출력
이 예시를 실행할 때 문자열
Hello World!
콘솔에 표시됩니다.
코드 토론
앞의 예에서
puts
함수의 매개 변수의 기본 봉송 처리가 기본값인 LPTSTR에서 LPSTR로 다시 작성되었습니다.MarshalAs 속성은 메소드 매개변수, 메소드 반환 값 및 구조 및 클래스 필드에 배치할 수 있습니다.메소드 반환 값에 대한 봉인 처리를 설정하려면 메소드 상의 메소드 블록에 MarshalAs 등록 정보를 반환 등록 정보 위치 재작성과 함께 배치합니다.예를 들어 명시적 설정
puts
방법으로 값을 반환하는 봉송 처리를 하려면 다음과 같이 하십시오....
[DllImport("msvcrt.dll")]
[return : MarshalAs(UnmanagedType.I4)]
public static extern int puts(
...
3. 사용자 정의 구조에 사용자 정의 봉인 처리 지정
비 트랜잭션 함수로 전달되거나 비 트랜잭션 함수에서 되돌아오는 구조와 클래스의 필드에 사용자 정의 봉송 처리 속성을 지정할 수 있습니다.구조 또는 클래스 필드에 MarshalAs 속성을 추가하면 됩니다.또한 StructLayout 속성을 사용하여 구조의 레이아웃을 설정하고 문자열 구성원의 기본 봉인 처리를 제어하며 기본 봉인 크기를 설정해야 합니다.
예제 3
이 예는 구조에 사용자 정의 봉송 처리 속성을 지정하는 방법을 설명한다.
다음 C 구조를 고려하십시오.
typedef struct tagLOGFONT
{
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;
C#에서는 다음과 같이 StructLayout 및 MarshalAs 속성을 사용하여 앞의 구조를 설명할 수 있습니다.
// logfont.cs
// compile with: /target:module
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public class LOGFONT
{
public const int LF_FACESIZE = 32;
public int lfHeight;
public int lfWidth;
public int lfEscapement;
public int lfOrientation;
public int lfWeight;
public byte lfItalic;
public byte lfUnderline;
public byte lfStrikeOut;
public byte lfCharSet;
public byte lfOutPrecision;
public byte lfClipPrecision;
public byte lfQuality;
public byte lfPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=LF_FACESIZE)]
public string lfFaceName;
}
그런 다음 다음과 같이 C# 코드에 구조를 사용할 수 있습니다.
// pinvoke.cs
// compile with: /addmodule:logfont.netmodule
using System;
using System.Runtime.InteropServices;
class PlatformInvokeTest
{
[DllImport("gdi32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr CreateFontIndirect(
[In, MarshalAs(UnmanagedType.LPStruct)]
LOGFONT lplf // characteristics
);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(
IntPtr handle
);
public static void Main()
{
LOGFONT lf = new LOGFONT();
lf.lfHeight = 9;
lf.lfFaceName = "Arial";
IntPtr handle = CreateFontIndirect(lf);
if (IntPtr.Zero == handle)
{
Console.WriteLine("Can't creates a logical font.");
}
else
{
if (IntPtr.Size == 4)
Console.WriteLine("{0:X}", handle.ToInt32());
else
Console.WriteLine("{0:X}", handle.ToInt64());
// Delete the logical font created.
if (!DeleteObject(handle))
Console.WriteLine("Can't delete the logical font");
}
}
}
실행 예
C30A0AE5
코드 토론
앞의 예에서
CreateFontIndirect
방법은 LOGFONT 유형의 매개 변수를 사용했다.MarshalAs 및 In 속성은 이 매개변수를 제한합니다.프로그램은 이 방법으로 되돌아오는 값을 16진 대문자 문자열로 표시합니다.4. 콜백 등록 방법
비 트랜잭션 함수를 호출하는 트랜잭션 리셋을 등록하려면 같은 매개 변수 목록으로 의뢰를 설명하고 PINvoke를 통해 실례를 전달하십시오.비 트랜지스터에서 함수 바늘로 표시됩니다.예를 들어 다음과 같은 비 관리형 함수
MyFunction
를 고려하면 이 함수는 콜백을 매개 변수 중 하나로 요구합니다.typedef void (__stdcall *PFN_MYCALLBACK)();
int __stdcall MyFunction(PFN_ MYCALLBACK callback);
관리된 코드에서 호출
MyFunction
하려면 위임을 선언하고 함수 선언에 DllImport를 첨부하고 필요에 따라 매개 변수나 반환 값을 봉인합니다.public delegate void MyCallback();
[DllImport("MYDLL.DLL")]
public static extern void MyFunction(MyCallback callback);
또한 위탁 실례의 생존 기간이 비 트랜잭션 코드를 덮어쓰는 생존 기간을 확보하십시오.그렇지 않으면 쓰레기 수거를 거친 후 위탁을 사용할 수 없습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
LoadLibrary에서 126 오류가 발생하면 원인이되는 파일 이름을 찾는 방법Loadlibrary에서 DLL을 동적으로 로드할 때 로드 실패입니다. 실패한 파일 이름은 알려주지 않습니다. 로드하고자 하는 DLL 자체를 로드할 수 없다면 이야기는 간단하지만, 대상 DLL이 다른 DLL을 로드하...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.