关于在C#中使用C ++ DLL函数的问题

时间:2011-07-26 23:59:02

标签: c# dll c++-cli

我有一个用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()函数

2 个答案:

答案 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文件编译为托管,将其他文件集编译为非托管文件。托管类不能包含非托管内容(除非它被声明为指针)。