我正在尝试在C ++ / CLI项目的混合模式中使用MimeTex.dll
。我包括dll:
#pragma comment(lib,"MimeTex.dll")
我尝试调用此方法:
CreateGifFromEq("expression","path");
但编译器通知它不知道CreateGifFromEq()方法。
我没有在网上找到有关如何在C ++中使用MimeTex.dll
的资源。我只是在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的混合模式下如何调用它?
答案 0 :(得分:1)
当然你打算写:
#pragma comment(lib,"MimeTex.lib")
换句话说,您将.lib文件传递给链接器而不是.dll。编译DLL时,将生成.lib文件。
但那不是你眼前的问题。编译器没有CreateGifFromEq
的声明。那是因为你没有在你的C ++代码中包含库的头文件。这样做可以解决问题。
如果你需要的只是一个函数,那么在你的C ++代码中声明它应该是微不足道的。
__declspec(dllimport) extern int CreateGifFromEq(char *expr, char *fileName);
您可能还需要将其包装在extern "C"
块中。
实际上,在查看了库之后,源代码提供的头文件并没有声明该函数,即使它存在于库中。
答案 1 :(得分:1)
在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并正常调用它们。
答案 2 :(得分:0)
有一种更清洁的做事方式:
创建C ++ / CLI项目。它将是您在C#和C ++之间的接口(这是C ++ / CLI的目标)。
让你的C#项目引用这个新程序集。
在新的C ++ / CLI项目中,配置项目选项,以便指向包含mimetex .h文件的目录,以便编译器编译项目,以及链接的.lib / .dll目录。
在C ++ / CLI部分中,您只需在函数内部编写C ++。它们暴露在你的C#程序集中,但在内部它只是像往常一样调用C ++函数。 (您应该查看C ++ CLI教程,了解如何处理字符串以将它们转换为本机字符或std :: string。我记得我必须查看它。)*
在C#部分中,您只需调用C ++ CLI项目程序集公开的函数,例如普通的C#函数,而不会注意它的后面的本机代码。