C#에서 C 함수를 호출할 수 있습니까?그물
Clib가 있고 이 라이브러리의 함수를 C# 어플리케이션에서 호출하고 싶습니다.Clib 파일을 링커 입력으로 추가하고 소스 파일을 추가 종속성으로 추가하여 Clib에 C++/CLI 래퍼 작성을 시도했습니다.
C 출력을 c# 어플리케이션에 추가하는 방법을 잘 모르기 때문에 이를 실현하는 더 좋은 방법이 있습니까?
마이 C 코드 -
__declspec(dllexport) unsigned long ConnectSession(unsigned long handle,
unsigned char * publicKey,
unsigned char publicKeyLen);
My CPP 래퍼 -
long MyClass::ConnectSessionWrapper(unsigned long handle,
unsigned char * publicKey,
unsigned char publicKeyLen)
{
return ConnectSession(handle, publicKey, publicKeyLen);
}
예를 들어 Linux의 경우 다음과 같습니다.
) 1) 을 합니다.C 파일,libtest.c다음 내용을 포함합니다.
#include <stdio.h>
void print(const char *message)
{
printf("%s\\n", message);
}
printf의 어떤 것이든 수 있어요.C호출할 라이브러리에서 기능을 수행합니다.「 」가 C++을 넣는 마세요C이름을 더럽히지 않기 위해서요.
② 성)를C#
using System;
using System.Runtime.InteropServices;
public class Tester
{
[DllImport("libtest.so", EntryPoint="print")]
static extern void print(string message);
public static void Main(string[] args)
{
print("Hello World C# => C++");
}
}
3).so 가 "/usr 와 표준 한 3) "/usr/lib" 의 libtest 가 될 수 .소우so을 /.DllNotFoundException libtest.so libtest.so / usr / lib 이로이 CWD 。export LD_LIBRARY_PATH=pwd
여기서부터의 크레딧
편집
Windows 의 경우는, 큰 차이가 없습니다.여기서 예를 들자면, 당신은 당신의 코드에 동봉만 하면 됩니다.*.cpp당신의 extern "C" 같은 거
extern "C"
{
//Note: must use __declspec(dllexport) to make (export) methods as 'public'
__declspec(dllexport) void DoSomethingInC(unsigned short int ExampleParam, unsigned char AnotherExampleParam)
{
printf("You called method DoSomethingInC(), You passed in %d and %c\n\r", ExampleParam, AnotherExampleParam);
}
}//End 'extern "C"' to prevent name mangling
그런 다음 컴파일을 하고 C# 파일에서 다음을 수행합니다.
[DllImport("C_DLL_with_Csharp.dll", EntryPoint="DoSomethingInC")]
public static extern void DoSomethingInC(ushort ExampleParam, char AnotherExampleParam);
그 다음 그것을 사용합니다.
using System;
using System.Runtime.InteropServices;
public class Tester
{
[DllImport("C_DLL_with_Csharp.dll", EntryPoint="DoSomethingInC")]
public static extern void DoSomethingInC(ushort ExampleParam, char AnotherExampleParam);
public static void Main(string[] args)
{
ushort var1 = 2;
char var2 = '';
DoSomethingInC(var1, var2);
}
}
UPDATE - 2019년 2월 22일 : 이 답변은 많은 표가 쇄신되고 있기 때문에 C 메서드라고 하는 더 나은 방법으로 업데이트하기로 했습니다.이전에 사용하라고 제안했습니다.unsafe은, 「」를 하는 것입니다.MarshalAs을 변환하기 위한 입니다. 물 netstring a까지char*또한 VS2017에서는 Win32 프로젝트가 없어지기 때문에 Visual C++ dll 또는 빈 프로젝트를 생성하여 수정해야 합니다.★★★★★★★★★★★★★★★★★★!
P/Invoke C# C는 C/Invoke C입니다.
C dll C # lbrary 작음 。
- 새로운 C# 라이브러리 프로젝트 작성 ('Wrapper'라고 부릅니다)
솔루션에 Win32 프로젝트를 추가하고 응용 프로그램 유형을 DLL로 설정합니다(CLIBRARY라고 부릅니다).
- 다른 모든 cpp/h 파일은 필요 없기 때문에 삭제할 수 있습니다.
- CLibrary.cpp 파일의 이름을 CLibrary.c로 변경합니다.
- CLibrary.h 헤더 파일 추가
이제 CLibrary 프로젝트를 구성하고 마우스 오른쪽 버튼을 클릭하여 속성으로 이동한 후 구성: "모든 구성"을 선택해야 합니다.
- [ Configuration Properties ]> [ C / C + + ]> [ Precompiled Headers ]에서 [Not using Precompiled Headers]를 설정합니다.
- 같은 C/C++ 브랜치로 [Advanced](상세설정)으로 이동하여 [C코드(/TC)로 컴파일]를 변경합니다.
- 다음으로 [Linker]브런치에서 [General]으로 이동하여 [Output File]를 [$(SolutionDir)]으로 변경합니다.Wrapper\$(프로젝트명).dll" 그러면 빌드된 C DLL이 C# 프로젝트 루트에 복사됩니다.
클라이브리.h
__declspec(dllexport) unsigned long ConnectSession(unsigned long handle,
unsigned char * publicKey,
unsigned char publicKeyLen);
클라이버러리
#include "CLibrary.h"
unsigned long ConnectSession(unsigned long handle,
unsigned char * publicKey,
unsigned char publicKeyLen)
{
return 42;
}
- CLibrary 프로젝트를 오른쪽 클릭하여 빌드하면 C# 프로젝트 디렉토리에 DLL이 표시됩니다.
- C# Wrapper 프로젝트를 오른쪽 클릭하여 기존 아이템을 추가하고 CLibrary.dll을 추가합니다.
- CLibrary.dll을 클릭하고 속성 페인으로 이동하여 "Copy to output Directory"를 "Copy Always"로 설정합니다.
Wrapper 프로젝트는 CLibrary에 의존하도록 하는 것이 좋습니다.CLibrary는 Wrapper 프로젝트를 우클릭하여 "Project Dependencies"로 이동하고 "CLibrary"를 체크함으로써 구축할 수 있습니다.실제 래퍼 코드의 경우:
ConnectSessionWrapper.cs
using System.Runtime.InteropServices;
namespace Wrapper
{
public class ConnectSessionWrapper
{
[DllImport("CLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
static extern uint ConnectSession(uint handle,
[MarshalAs(UnmanagedType.LPStr)] string publicKey,
char publicKeyLen);
public uint GetConnectSession(uint handle,
string publicKey,
char publicKeyLen)
{
return ConnectSession(handle, publicKey, publicKeyLen);
}
}
}
전화나 해GetConnectSession, 그리고 그것은 다시 돌아올 것이다.42.
결과:

네, VS 2010을 열고 Goto File -> New -> Project -> Visual C++ -> Win32 -> Win32 Project에 이름을 붙입니다(내 경우는 HelloWorldDll) 다음 창에서 [DLL]를 선택하고 [Project]를 선택합니다.
[ Solution Explorer ]탭은 보통 VS 창의 오른쪽에서 오른쪽 버튼을 클릭하여 [Source Files]-> [ Add Item ]-> [ C+ + file ( . cpp ) ]를 오른쪽 클릭하여 이름을 지정합니다(내 경우는 [Hello World ] ) 。
그런 다음 새 클래스에 이 코드를 붙여넣습니다.
#include <stdio.h>
extern "C"
{
__declspec(dllexport) void DisplayHelloFromDLL()
{
printf ("Hello from DLL !\n");
}
}
이제 프로젝트를 빌드합니다.프로젝트 DEBUG 폴더로 이동하면 다음 항목이 나타납니다.Hello World Dll.dll.
이제 dll에 액세스하는 C# 어플리케이션을 만듭니다.Goto File -> New -> Project -> Visual C# -> Console Application에 이름(CallDllCSharp)을 붙입니다.다음 코드를 복사하여 메인에 붙여넣습니다.
using System;
using System.Runtime.InteropServices;
...
static void Main(string[] args)
{
Console.WriteLine("This is C# program");
DisplayHelloFromDLL();
Console.ReadKey();
}
프로그램을 빌드합니다.이제 두 앱이 모두 구축되었으므로 이를 사용하여 *.discs와 .exe(bin/discs/.exe)를 같은 디렉토리에 저장하고 응용 프로그램 출력을 실행합니다.
이것은 C# 프로그램입니다.
DLL에서 헬로!
이것으로 당신의 문제가 해결되기를 바랍니다.
참고 자료:
메모: 다음 코드는 DLL로부터의 여러 메서드에 대한 것입니다.
[DllImport("MyLibc.so")] public static extern bool MyLib_GetName();
[DllImport("MyLibc.so")] public static extern bool MyLib_SetName(string name);
[DllImport("MyLibc.so")] public static extern bool MyLib_DisplayName(string name);
public static void Main(string[] args)
{
string name = MyLib_GetName();
MyLib_SetName(name);
MyLib_DisplayName(name);
}
P/Invoke 메서드는 지금까지 광범위하고 반복적으로 설명되어 왔습니다.여기서 놓치고 있는 것은 C++/CLI 방식에는 큰 이점이 있다는 것입니다.안전요청을 합니다.C 함수의 콜이 하늘을 향해 블라인드를 쏘는 것과 같은 P/Invoke와는 대조적으로(이 비교가 허가되어 있는 경우), C 함수를 호출할 때 함수 인수를 체크하는 사람은 없습니다.이 경우 C++/CLI를 사용하면 일반적으로 사용할 함수 프로토타입이 포함된 헤더 파일을 포함할 수 있습니다.잘못된 인수/많은 인수/거의 인수를 사용하여 C 함수를 호출하는 경우 컴파일러는 이를 알려줍니다.
일반적으로 어느 쪽이 좋은지 말할 수 없다고 생각합니다만, 솔직히 어느 쪽도 마음에 들지 않습니다.
언급URL : https://stackoverflow.com/questions/11425202/is-it-possible-to-call-a-c-function-from-c-net
'programing' 카테고리의 다른 글
| memcpy() vs memmove() (0) | 2022.08.07 |
|---|---|
| Java에서의 RESTful 콜 (0) | 2022.08.07 |
| 현재 vue 구성 요소의 메서드를 기본 프로펠러 값으로 사용 (0) | 2022.08.07 |
| VueJS 싱글 파일 컴포넌트(타이프 스크립트 포함):모듈 정보를 찾을 수 없습니다.표시하다 (0) | 2022.08.07 |
| VueJ가 계산한 속성이 HTML 코드를 반환하는 경우 어떻게 처리합니까? (0) | 2022.08.07 |