我有一个用C ++编写的DLL,然后在C#程序中使用。 C#程序引用DLL并调用类,并可以使用DLL中定义的函数。
现在我想在DLL中添加其他函数,这样我就可以在C#中运行C ++代码。我按照如何定义DLL中的其他函数的示例; .h和.cpp和我创建一个执行代码的新函数。我把它放在与之前定义的函数相同的位置,但是当我把DLL放在我的C#代码中时,我的函数不存在。当我创建DLL类的实例时,我的函数不是它的一部分。
我将它作为类的公共函数放在.h中,并将其代码运行在.cpp中但未找到它。
为什么我的C#程序看不到我所做的功能,即使它跟其他功能一样?
更新
code.h:
#pragma once
#include <windows.h>
#include <PvDisplayWnd.h>
#include <vfw.h>
#include "NPvResult.h"
#include "NPvDeviceInfo.h"
#include "NPvBuffer.h"
#include <string>
using namespace System;
using namespace System::Runtime::InteropServices;
public ref class NPvDisplayWnd
{
public :
NPvDisplayWnd();
bool Handle();
NPvResult^ ShowModeless(long locx, long locy, long x, long y);
NPvResult^ ShowModal();
NPvResult^ NPvDisplayWnd::Create();
int^ Display( NPvBuffer^ aBuffer, int^ x);
NPvResult^ Work( const std::string afilename, unsigned short asizex, unsigned short asizey, unsigned short aBPP, double aFPS);
NPvResult^ Close();
NPvResult^ DoEvents();
}
code.cpp:
#include "NPvDisplayWnd.h"
NPvDisplayWnd::NPvDisplayWnd(){code}
NPvResult^ NPvDisplayWnd::Create(){code}
bool NPvDisplayWnd::Handle()
NPvResult^ NPvDisplayWnd::ShowModeless(long locx, long locy, long x, long y){code}
NPvResult^ NPvDisplayWnd::ShowModal(){code}
int^ NPvDisplayWnd::Display( NPvBuffer^ aBuffer, int^ x){code}
NPvResult^ NPvDisplayWnd::DoEvents(){code}
NPvResult^ NPvDisplayWnd::Work( const std::string aFileName, unsigned short aSizeX, unsigned short aSizeY, unsigned short aBPP, double aFPS){code}
NPvResult^ NPvDisplayWnd::Close(){code}
我添加的功能是Work()函数。如果我构建它并将其放在我的C#代码中,它会看到除工作之外的所有功能。为了确保我使用正确的.dll,我将ShowModeless()的名称更改为ShowModeless__F()并重新构建它并将其添加到我的C#并继续进行更改,但我仍然没有看到我的Work()函数
答案 0 :(得分:0)
在Windows上,您必须显式导出符号,以便用户能够通过DLL访问它们。这是使用__declspec(export)
语法完成的。在编译和链接DLL时需要这样做。
现在我们知道你使用的是C ++ / CLI而不是普通的C ++,我们可以看到一个问题。 Work
需要std::string
。但Work
旨在成为托管函数,托管代码不能将std::string
作为参数。您需要改为使用托管字符串类型。
答案 1 :(得分:0)
无法在C#中导入本机C ++类。您需要在现有C ++ DLL中使用C ++ / CLI功能,以便托管客户端(如C#)可以导入类。
namespace XX
{
public ref class YourClass{...};
}
它将在YourClass
命名空间下导出托管类XX
。您需要使用/CLR
编译器标志。
您可以将一组CPP文件编译为托管,将其他文件集编译为非托管文件。托管类不能包含非托管内容(除非它被声明为指针)。