我想暴露一個函數從一個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,一旦我取得了一些進展,就會更新。 –