C #에서 C ++ / CLI를 어떻게 호출합니까?
프로그램의 산술 계산을 담당하는 C ++로 구현 된 클래스와 WPF를 사용하는 인터페이스가 있습니다. C #으로 입력을 처리하지만 C ++ 클래스를 어떻게 사용할 수 있습니까?
상호 작용하기 위해 관리되는 C ++ 래퍼 클래스를 만드는 방법에 대한 몇 가지 의견을 보았지만 어디서부터 시작해야할지 모르겠습니다. 다른 모든 코드와 함께 어떻게 컴파일할지 알지 못합니다. 나는 이것에 대한 자습서를 실제로 찾을 수 없으며 Google이 관리되는 C ++에 대해 보여주는 내용은 실제로 도움이되지 않는 것 같습니다.
저를 도와 줄 게 있나요? 이것은 나에게 비합리적으로 보이지 않습니다.
EDIT m3rLinEz 솔루션을 시도했지만 BadImageFormatException이 발생합니다. DLL이 생성되지 않았기 때문이라고 생각합니다. 나는 말한대로 모든 것을했다, 무슨 일이 일어 났는지 모른다. 어떤 아이디어?
C ++ / CLI를 보셨습니까?
아주 짧은 예를 들어 보겠습니다. 다음은 Visual C ++-> CLR-> 클래스 라이브러리 프로젝트의 소스 파일입니다. 기본적으로 Windows 사용자 이름을 가져와 반환합니다.
이 파일을 컴파일하려면 프로젝트 설정으로 이동하여 "추가 종속성"을 "부모에서 상속"으로 표시해야합니다. Windows 라이브러리 (kernel32.lib, user32.lib, ..)를 사용하고 있기 때문입니다.
// CSCPP.h
#pragma once
#include "windows.h"
using namespace System;
namespace CSCPP {
public ref class Class1
{
// TODO: Add your methods for this class here.
public:
String^ GetText(){
WCHAR acUserName[100];
DWORD nUserName = sizeof(acUserName);
if (GetUserName(acUserName, &nUserName)) {
String^ name = gcnew String(acUserName);
return String::Format("Hello {0} !", name);
}else{
return gcnew String("Error!");
}
}
};
}
이제 새 C # 프로젝트를 만들고 첫 번째 C ++ / CLI 클래스 라이브러리 프로젝트에 대한 참조를 추가합니다. 그런 다음 인스턴스 메서드를 호출합니다.
namespace CSTester
{
class Program
{
static void Main(string[] args)
{
CSCPP.Class1 instance = new CSCPP.Class1();
Console.WriteLine(instance.GetText());
}
}
}
이것은 내 컴퓨터에서 다음과 같은 결과를 얻었습니다.
안녕하세요 m3rlinez!
C++/CLI is basically a managed extension over C++ standard. It allows you to utilize CLR classes and data types in your C++/CLI project and also expose this to managed language. You can created a managed wrapper for your old C++ library using this. There are some weird syntaxes such as String^
to define reference type to CLR String. I find "Quick C++/CLI - Learn C++/CLI in less than 10 minutes" to be useful here.
There are at least three ways to call unmanaged code from managed in the same process:
- C++/CLI
- Platform Invoke
- Wrap your C++ in a COM object
At work we use C++/CLI for this, it seems to work.
I would create a standard (non COM/Managed) Dynamic Link Library as described here and then use the DllImport attribute (platform invoke) in the c# code to access the exported functions.
The key point from that article:
Note the __declspec(dllexport) modifier in the method declarations in this code. These modifiers enable the method to be exported by the DLL so that it can be used by other applications. For more information, see dllexport, dllimport.
This is a lighter weight alternative to an actual COM interop wrapper and avoids issues such as registration etc (the DLL can simply be placed in the application directory) .
Another alternative is It Just Works (IJW). This is probably a better choice if you have managed C++ code and need to access this from other .NET languages. But this is only an option if you are able/happy to convert your unmanaged C++ to managed C++ though.
I would stay away from P/Invoke as it's pretty slow compared to IJW (It Just Works). The latter allows you to seamlessly interweave managed and and unmanaged c++. All you have to do is to create a managed c++ assembly, write a managed class that is visible from c# and call the unmanaged code out of that.
Uhm... OK. I was under the impression that P/Invoke calls were slower which they are inherintly not. However, by having explicit control over marshalling, you can make your C++/CLI version to perform better in a lot of the cases.
Here is Microsoft's article about both mechanisms:
http://msdn.microsoft.com/en-us/library/ms235282.aspx
Advantages of IJW
- There is no need to write DLLImport attribute declarations for the unmanaged APIs the program uses. Just include the header file and link with the import library.
- The IJW mechanism is slightly faster (for example, the IJW stubs do not need to check for the need to pin or copy data items because that is done explicitly by the developer).
- It clearly illustrates performance issues. In this case, the fact that you are translating from a Unicode string to an ANSI string and that you have an attendant memory allocation and deallocation. In this case, a developer writing the code using IJW would realize that calling _putws and using PtrToStringChars would be better for performance.
- If you call many unmanaged APIs using the same data, marshaling it once and passing the marshaled copy is much more efficient than re-marshaling every time.
There are aesthetic advantages as well:
- C# code looks like C# code without any interop'y weirdness.
You don't have to define
DLLImport
attribute, you don't have to define any of the data structures (also with p/invoke specific attributes) which could look like this:[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct DevMode { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmDeviceName; }
- You don't have to convert all parameter primitive types into their .NET counterparts (there is table on this page that lists how managed types map to unmanaged types).
- You get to work with C++/CLI which is really fun to learn and is really polished. It's come a long way since VS 2003 and is now a fully featured .NET language. Microsoft documentation for it is pretty good, as is all the IJW information.
- Doing C++ interop in C++/CLI feels very natural as opposed to C#. This is completely subjective, but I would much rather prefer to do string marshalling in C++ that do
Marshal.PtrToString(ptr)
. - If exposing an API you would probably want to wrap up all P/Invoke stuff in another layer, so you don't have to deal with P/Invoke ugliness. This way you have the overhead of all the marshalling AND the C# layer around it. With C++/CLI the marshalling and the interop abstraction are in one place, and you can choose how much marshalling you need.
IMHO if you are calling an odd function in Windows SDK, go with P/Invoke. If you are exposing a moderately complex C++ API to the managed world, definitely C++/CLI.
참고URL : https://stackoverflow.com/questions/2211867/how-do-i-call-c-cli-from-c
'Programing' 카테고리의 다른 글
첨부 파일이있는 이메일을 보내기위한 Android Intent (0) | 2020.11.21 |
---|---|
전체 큰 파일을 Mmap () (0) | 2020.11.21 |
SOLID 대 YAGNI (0) | 2020.11.21 |
“Apache Harmony를 사용하는 이유”또는“Android에서 Java 8을 사용하는 방법” (0) | 2020.11.21 |
웹 사이트에서 검색 기능을 어떻게 구현합니까? (0) | 2020.11.21 |