c# EXE /非托管c++ Unicode DLL链接到非托管c++ ANSI DLL崩溃
C# EXE w/ Unmanaged C++ Unicode DLL linking to unmanaged C++ ANSI DLL crash
我有一个c#可执行文件,它加载在一个DLL中,这是一个unicode非托管c++ DLL。这个非托管的c++ DLL也链接到另一个DLL,这个非托管的c++ DLL恰好是ANSI。
当我运行我的c#可执行文件时,程序最终在DLL调用的ANSI部分崩溃(我还没有能够拉异常)。然而,通过简单地将ANSI DLL切换到Unicode,一切都可以工作,除了有第三个DLL,它来自另一家公司的SDK,它对Unicode/ANSI有明显的敏感性,所以如果调用DLL是在ANSI中,它工作得最好。
所以我们只有一个可执行的调用函数在一个非托管unicode c++ DLL中,它作为一个非托管ANSI c++ DLL的包装器,它是一个最终的非托管DLL的包装器,我们没有关于它的信息。
将两个中间DLL切换到unicode可以纠正崩溃,只是让它与第三个单独的供应商DLL一起失败(但不会因异常而灾难性地失败,它们只是输出不正确)。我们不能将第一个DLL转换为ANSI,因为我们在c#应用程序中使用Unicode,这是我们的标准。
我不明白二阶DLL的敏感性。有人能给我解释一下吗?
我使用这个类来动态链接到DLL的:
static class NativeMethods
{
[DllImport("kernel32", SetLastError = true)]
public static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32", SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32", SetLastError = true)]
public static extern IntPtr LoadLibrary(string dllToLoad);
}
的委托类似于:
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Auto)]
private delegate int ExampleFunction();
和切换CharSet。自动转换为。ansi或。unicode无效。
带有函数调用,诸如:
m_pDll = NativeMethods.LoadLibrary(@strDLLName);
if (m_pDll == IntPtr.Zero) this.Close();
IntPtr pAddressForExampleFunction = NativeMethods.GetProcAddress(m_pDll, "ExampleFunction");
if (pAddressForExampleFunction == IntPtr.Zero) this.Close();
m_ExampleFunction = (ExampleFunction)Marshal.GetDelegateForFunctionPointer(pAddressForExampleFunction, typeof(ExampleFunction));
带函数调用:
m_ExampleFunction();
编辑:根据请求,c++ EXE对应文件:
在.h文件中定义为成员:
ExampleFunction pExampleFunction;
typedef BOOL __declspec(dllimport) (*ExampleFunction)();
pExampleFunction被定义为:
pExampleFunction= (ExampleFunction) ::GetProcAddress(m_hDll,"ExampleFunction");
使用这个调用,prior:
m_hDll = AfxLoadLibrary(m_DllName);
问题很可能发生在两个非托管dll之间,因为它们之间的字符串数据传输不一致。
ANSI/Unicode dll标志是编译时属性。编译器根据此标志选择类型和函数。TCHAR
对于Unicode编译为wchar_t
,对于ANSI编译为char
。例如,如果一个dll期望得到长度为符号的wchar_t*
,但实际接收到的值是char*
,那么这种差异可能会导致超出边界的问题。这是未定义行为,可能导致应用程序崩溃。
许多Win API函数有两个版本xxxW
(Unicode)和xxxA
(ANSI)。例句:
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif.
在c#端,CharSet
属性控制字符串封送,并决定平台调用如何在DLL中查找函数名。它不会影响非托管c++ dll内的进一步字符串操作。方法
[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Auto)]
private delegate int ExampleFunction();
没有要封送的字符串,因此CharSet
不会影响它。如果在非托管c++端有两个此方法的实现,则可能存在差异:ExampleFunctionA
用于ANSI, ExampleFunctionW
用于Unicode。
- 挂起和取消挂起一个文件DLL
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 导入库可以跨dll版本工作吗
- 从C++dll访问C#中的一行主要参数
- 链接到自行创建的dll失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- C++:将外部库链接到dll库
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 不同的Visual Studio版本中缺少.dll
- 从DLL中删除类的实例
- 如何包装第三方DLL在R中使用
- 使用c#访问c++dll中带有char*参数的函数时发生AccessViolationException
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Python ctypes:不会按预期加载 dll
- 在 C++/CLI 中将 .NET 事件从一个 DLL 引发到另一个 DLL