我必须在新的C#项目中使用C ++现有代码。此C ++代码是DLL中包含的非托管代码。我的一位同事已经用" C"代码,但在我的情况下,我的DLL包含一个" Class"我不知道是否可以这样做。
在我的C#应用程序中使用此C ++类的正确方法是什么?
更新
感谢所有的论文答案。我按照这篇文章Using Unmanaged C Libraries DLLS in NET Application
尝试了一个简单的课程我的初始课程是在Borland C ++ Builder 6上编码的:
Test.cpp的:
#include <basepch.h>
#pragma hdrstop
#include "Test.h"
#pragma package(smart_init)
__fastcall TTest::TTest() {
//rien
}
__fastcall TTest::~TTest() {
//rien
}
void __fastcall TTest::setNombre(int nbr) {
nombre = nbr;
}
int __fastcall TTest::getNombre() {
return nombre;
}
Test.h:
#ifndef TestH
#define TestH
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <string.h>
#include <stdio.h>
#include <StrUtils.hpp>
#include <time.h>
class PACKAGE TTest
{
private:
int nombre;
protected:
public:
__fastcall TTest();
__fastcall ~TTest();
void __fastcall setNombre(int nbr);
int __fastcall getNombre();
};
extern PACKAGE TTest *Test;
#endif
这个类的编译没问题:D
然后我尝试在文章中创建非托管类。但是我在C ++ Builder中创建这个类时遇到了问题。
Unmanaged.cpp:
#pragma hdrstop
#include "Unmanaged.h"
#pragma package(smart_init)
struct UnmanagedClasseTest
{
int nombre;
[DllImport("ClasseTest.dll", EntryPoint="@TTest@$bctr$qqrv", CallingConvention=CallingConvention::ThisCall)]
static void ctor(UnmanagedClasseTest* c);
[DllImport("ClasseTest.dll", EntryPoint="@TTest@$bdtr$qqrv", CallingConvention=CallingConvention::ThisCall)]
static void dtor(UnmanagedClasseTest* c);
[DllImport("ClasseTest.dll", EntryPoint="@TTest@setNombre$qqri", CallingConvention=CallingConvention::ThisCall)]
static void setNombre(UnmanagedClasseTest* c, int nbr*);
[DllImport("ClasseTest.dll", EntryPoint="@TTest@getNombre$qqrv", CallingConvention=CallingConvention::ThisCall)]
static int getNombre(UnmanagedClasseTest* c);
static void Uctor(UnmanagedClasseTest* c) {
ctor(c);
}
static void Udtor(UnmanagedClasseTest* c) {
dtor(c);
}
static void UsetNombre(UnmanagedClasseTest* c, int i) {
nombre = setNombre(c);
}
static int UgetNombre(UnmanagedClasseTest* c) {
return getNombre(c);
}
};
Unmanaged.h:
#ifndef UnmanagedH
#define UnmanagedH
static void ctor(UnmanagedClasseTest* c);
static void dtor(UnmanagedClasseTest* c);
static void setNombre(UnmanagedClasseTest* c, int nbr*);
static int getNombre(UnmanagedClasseTest* c);
static void Uctor(UnmanagedClasseTest* c);
static void Udtor(UnmanagedClasseTest* c);
static void UsetNombre(UnmanagedClasseTest* c, int i);
static int UgetNombre(UnmanagedClasseTest* c);
#endif
当我想编译这个非托管类时,我有以下错误:/
[C++ Erreur] Unmanaged.h(6): E2147 'UnmanagedClasseTest' ne peut pas démarrer une déclaration de parameter
[C++ Erreur] Unmanaged.h(7): E2147 'UnmanagedClasseTest' ne peut pas démarrer une déclaration de parameter
[C++ Erreur] Unmanaged.h(8): E2451 Symbole 'UnmanagedClasseTest' non define
[C++ Erreur] Unmanaged.h(9): E2147 'UnmanagedClasseTest' ne peut pas démarrer une déclaration de parameter
[C++ Erreur] Unmanaged.h(10): E2147 'UnmanagedClasseTest' ne peut pas démarrer une déclaration de parameter
[C++ Erreur] Unmanaged.h(11): E2147 'UnmanagedClasseTest' ne peut pas démarrer une déclaration de parameter
[C++ Erreur] Unmanaged.h(12): E2147 'UnmanagedClasseTest' ne peut pas démarrer une déclaration de parameter
[C++ Erreur] Unmanaged.h(13): E2147 'UnmanagedClasseTest' ne peut pas démarrer une déclaration de parameter
[C++ Erreur] Unmanaged.cpp(17): E2040 Déclaration terminée incorrectement
[C++ Erreur] Unmanaged.cpp(20): E2040 Déclaration terminée incorrectement
[C++ Erreur] Unmanaged.cpp(23): E2040 Déclaration terminée incorrectement
[C++ Erreur] Unmanaged.cpp(26): E2040 Déclaration terminée incorrectement
[C++ Erreur] Unmanaged.cpp(30): E2034 Impossible de convertir 'UnmanagedClasseTest *' en 'int *'
[C++ Erreur] Unmanaged.cpp(30): E2342 Mauvaise correspondance de type dans le paramètre 'c' ('int *' désiré, 'UnmanagedClasseTest *' obtenu)
[C++ Erreur] Unmanaged.cpp(33): E2034 Impossible de convertir 'UnmanagedClasseTest *' en 'int *'
[C++ Erreur] Unmanaged.cpp(33): E2342 Mauvaise correspondance de type dans le paramètre 'c' ('int *' désiré, 'UnmanagedClasseTest *' obtenu)
[C++ Erreur] Unmanaged.cpp(36): E2268 Appel à une fonction non définie 'setNombre'
[C++ Erreur] Unmanaged.cpp(36): E2231 Le membre UnmanagedClasseTest::nombre ne peut pas être utilisé sans un objet
[C++ Erreur] Unmanaged.cpp(39): E2034 Impossible de convertir 'UnmanagedClasseTest *' en 'int *'
[C++ Erreur] Unmanaged.cpp(39): E2342 Mauvaise correspondance de type dans le paramètre 'c' ('int *' désiré, 'UnmanagedClasseTest *' obtenu)
答案 0 :(得分:1)
我可以提出2个解决方案。 (1)通过标记__declspec(dllexport)导出整个C ++。它的所有方法都将从DLL中导出,并带有一些损坏的名称。找到这些名称(例如通过Depends实用程序)并在C#代码中编写DllImport包装。
(2)在班级中实施基本COM功能并使用COM interop。最小动作集:
a)实现IUnknown和IMarshal方法:
class YourClass: public IMarshal
{
// override AddRef, Release, QueryInterface and Marshal here
...
int __declspec(stdcall) foo(int x);
}
b)然后用C#进行ComImport你的课程:
[ComImport, Guid("5BADB572-FE70-4602-8854-E4B461FC5DAE")]
class YourClass
{
[PreserveSig] int foo(int x);
}
c)编写一个创建YourClass实例的C ++函数,从DLL中导出并为其编写DllImport包装。
答案 1 :(得分:0)
完成任务有几个先决条件。
假设您的dll(mycpp.dll)位于“c:\ mycpp.dll”位置,并且有一个名为“ Sum ”的方法,需要两个int参数a和b分别返回int。您可以使用以下代码:
public class Program
{
[DllImport(@"c:\mycpp.dll")]
private static extern int Sum(int a, int b);
static void Main(string[] args)
{
Console.WriteLine(Sum(3,5));
}
}
找到原始代码