我正在尝试在C++/CLI项目的混合模式下使用MimeTex.dll
。我包含的dll来自:#pragma comment(lib,"MimeTex.dll")
我试着调用这个方法:CreateGifFromEq("expression","path");
但是编译器通知它不知道CreateGifFromEq()方法。
我在网上找不到how to use MimeTex.dll
in C++的资源。我只是发现如何在Pinvok的this link中使用它和C#,如下所示:
[System.Security.SuppressUnmanagedCodeSecurity()]
internal class NativeMethods
{
private NativeMethods()
{ //all methods in this class would be static
}
[System.Runtime.InteropServices.DllImport("MimeTex.dll")]
internal static extern int CreateGifFromEq(string expr, string fileName);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
internal extern static IntPtr GetModuleHandle(string lpModuleName);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
[return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
internal extern static bool FreeLibrary(IntPtr hLibModule);
}
然后这样叫它:
NativeMethods.CreateGifFromEq(equation, tempGifFilePath);
如何在没有Pinvok的C++/CLI混合模式下调用它?
发布于 2013-03-28 16:47:33
你肯定是想写:
#pragma comment(lib,"MimeTex.lib")
换句话说,将.lib文件传递给链接器而不是.dll。编译DLL时,将生成一个.lib文件。
但这不是你的当务之急。编译器没有针对CreateGifFromEq
的声明。这是因为您的C++代码中没有包含该库的头文件。这样做应该可以解决问题。
如果只需要一个函数,那么在C++代码中声明它应该很简单。
__declspec(dllimport) extern int CreateGifFromEq(char *expr, char *fileName);
您可能还需要将其包装在extern "C"
块中。
实际上,在查看了该库之后,与源代码一起提供的头文件并没有声明该函数,即使它存在于库中。
发布于 2013-03-28 16:49:14
在C++/CLI中,你可以像在C#中一样使用P/Invoke。
如果您不想使用P/Invoke,另一种方法是使用LoadLibrary加载DLL,并使用GetProcAddress获取指向函数的指针。
下面是C++/CLI中C#代码的等价物:
using namespace System;
using namespace System::Runtime::InteropServices;
private ref class NativeMethods abstract sealed
{
internal:
[DllImport("MimeTex.dll")]
static int CreateGifFromEq(String^ expr, String^ fileName);
[DllImport("kernel32.dll")]
static IntPtr GetModuleHandle(String^ lpModuleName);
[DllImport("kernel32.dll")]
[returnvalue: MarshalAs(UnmanagedType::Bool)]
static bool FreeLibrary(IntPtr hLibModule);
};
正如您所看到的,除了一些微小的语法变化外,它与C#代码几乎相同。
下面是如何使用LoadLibrary和GetProcAddress (它的优点是不需要封送处理,这在C++中是不必要的):
HMODULE hModule = LoadLibrary(L"MimeTex.dll");
int (*fpCreateGifFromEq)(WCHAR*, WCHAR*) = GetProcAddress(hModule, "CreateGifFromEq");
(*fpCreateGifFromEq)(L"expression", L"filename");
你不需要为GetModuleHandle和FreeLibrary做这件事,因为它们来自kernel32.dll,所以你可以只包含Windows.h并正常调用它们。
发布于 2013-03-28 16:55:29
有一种更干净的方式做事情:
创建一个C++/CLI项目。它将是您在C#和C++之间的接口(这就是C++/CLI的目标)。
使您的C#项目具有对此新程序集的引用。
在新的C++/CLI项目中,配置项目选项,使其指向包含用于编译器编译项目的mimetex .h文件的目录,以及指向包含.lib/.dll的链接器的目录。
在C++/CLI部分中,您只需在函数内部编写C++即可。它们向您的C#程序集公开,但在内部只是像往常一样调用C++函数。(您应该查看C++CLI教程以了解如何处理字符串以将其转换为本机字符或std::string。我记得我不得不看着它。)*
在C#部件中,您只需像调用普通C#函数一样调用C++CLI项目程序集公开的函数,而不会注意到它的本机代码是在后面调用的。
https://stackoverflow.com/questions/15687468
复制相似问题