我想暴露一个函数从一个DLL(我们将调用foo.dll)在C#中使用。但是,我没有访问源,所以我想我可能会写一个第二个 DLL(bar.dll),其中包含第一个,通过返回foo.dll的结果重新实现函数。我确实有.lib和.h文件,所以我希望我可以写一个小工具来浏览标题并生成我的'wrapper'dll(这是正确的词吗?)包装C++ DLL通过第二次加载在C#
我已经设置一个非常简单的测试,我自己实现foo.dll。我是非常对新的C++所以请温柔。
foo.h中
#pragma once
double Add(double a, double b);
Foo.cpp中
#include <stdio.h>
#include "foo.h"
double Add(double a, double b)
{
return a + b;
}
我建立这个和引用的.lib到我的项目吧,在foo.h.沿着复制
bar.h
#pragma once
extern "C"
{
namespace foo {
#include "foo.h"
}
__declspec(dllexport) double Add(double a, double b);
}
bar.cpp
#include <stdio.h>
#include "bar.h"
__declspec(dllexport) double Add(double a, double b)
{
return foo::Add(a, b);
}
到目前为止那么简单。然后我试图使用的DllImport带入C#这正是如此:
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport("bar.dll", CallingConvention = CallingConvention.StdCall)]
private static extern double Add(double a, double b);
static void Main(string[] args)
{
Console.WriteLine("PRE");
Console.WriteLine(Add(1.5, 8.5));
Console.WriteLine("POST");
Console.ReadKey();
}
}
}
然而,当我运行此我只是得到“PRE”输出和程序只是等待。到目前为止,我已经通过错误消息排除了故障,但我不确定如何解决在这种情况下发生的情况。
如果我重新实现bar.cpp返回A + B的C#应用程序运行正常,输出: PRE 10.0 POST
我已经通过关于这个问题的好很多职位读,一些建议在声明我的变量时在名称前面添加__stdcall,但这会给我一个StackOverflow错误。
这是我的第一篇SO帖子(尽管当然我一直潜伏多年),所以请随时告诉我是否可以做任何事情来改善问题。
有时使用P/Invoke是不可能的(例如导出的方法有std :: string),有时使用P/Invoke(只是编译或试图追踪奇怪的短时间失败)非常困难。在这些情况下,你必须编写用C++/CLI编写的中间层。使用此选项的另一个优点是可以将C++ API转换为一些管理友好的API。有关C++/CLI的建议,[有一本Marcus Heege出色的书](https://www.amazon.com/Expert-Visual-CLI-Programmers-Experts/dp/1590597567)。 –
原始的Add()函数不在foo名称空间中。很不清楚你用什么大锤让酒吧项目链接。但它“不起作用”并不意外。 –
感谢您的书推荐。我正在调查Dan int的建议,他在下面回答了C++/CLI,一旦我取得了一些进展,就会更新。 –