我遇到了我创建的C++/CLI混合模式DLL的问题.卸载时抛出异常,因为使用它的.NET应用程序退出.在DLL_PROCESS_DETACH执行之后,DLL使用自动注册的atexit() / __onexit()函数执行运行时清理并抛出以下异常:
Unhandled exception at 0x752bb9bc (KernelBase.dll) in psstestm.exe:
0xC0020001: The string binding is invalid.
Run Code Online (Sandbox Code Playgroud)
我已经将问题跟踪到一个atexit()由静态boost异常对象注册的调用get_static_exception_object().
function_to_call 0x0f560410 _t2m@???__Fep@?1???$get_static_exception_object@Ubad_exception_@exception_detail@boost@@@exception_detail@boost@@YA?AVexception_ptr@1@XZ@YAXXZ@?A0x0a546e27@@YAXXZ void (void)*
Run Code Online (Sandbox Code Playgroud)
我使用boost_1_47大部分静态链接,除了boost :: thread,动态链接以避免加载器锁.我也尝试动态链接所有的助手,这没有帮助.所有的升压包括都被#pragma unmanaged块包围.
我希望有人有类似的问题或知道解决方案?
谢谢,马克
这是异常发生之前的调用堆栈:
psscorem.dll!_CRT_INIT(void * hDllHandle=0x0f4b0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 413 C
psscorem.dll!__DllMainCRTStartup(void * hDllHandle=0x0f4b0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 526 + 0x11 bytes C
psscorem.dll!_DllMainCRTStartup(void * hDllHandle=0x0f4b0000, unsigned long dwReason=0, void * lpreserved=0x00000001) Line 476 + 0x11 bytes …Run Code Online (Sandbox Code Playgroud) C++/CLI是非常强大的语言.它是唯一可以无缝组合托管和非托管代码的CLR语言.有多少软件开发人员(在本网站上)使用这种语言?你在什么样的项目中使用它?它是对遗留代码的修改还是原始软件的创建?你能比较旧的Managed C++和新的C++/CLI吗?您如何看待C++/CLI的当前质量和未来?
我想在.NET中使用C++类,但我在使用Visual Studio(2008)构建时遇到了问题.
我有一个非托管类A(使用/ clr编译的C++).我创建了一个C++/clr类'Class1',它将A和匹配的方法委托包装到A的方法中.
如果我在Class1(托管)的类库项目中包含A类的单元源文件我没有问题所有链接和工作正常,但我有很多非管理的C++类,如A和我想把它们放在DLL中并链接到DLL到托管库(类包装器).[我实际上并不认为此时需要将这些DLL链接在一起,但编译器似乎需要它,给出下面显示的相同错误.]
我创建了VisualC++/CLR/Class库并添加了我的C++类(下面列出的A)并构建.[我使用了默认设置,但是在项目链接器设置中我已经尝试使用"是"和"否"注册输出.]没有错误,并且创建了.DLL文件.
我创建了VisualC++/CLR/Class库并创建了包装类'Class1'我使用了所有默认设置.在项目属性下,我单击了"引用""添加新引用"并选择了第一步中创建的DLL.
我收到链接器错误:
test_NET_library.obj : error LNK2028: unresolved token (0A000009) "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2028: unresolved token (0A00000A) "public: int __thiscall Z::A::m2(int,int)" (?m2@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m2(int,int)" (?m2@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: …Run Code Online (Sandbox Code Playgroud) 我有一个简单的控制台测试应用程序ConsoleApplication1.exe,它引用另一个程序集clipper.dll.
在我测试过的3台机器上,可以将两个文件放在例如c:\test\和执行中ConsoleApplication1.exe.
在另一台恰好是客户端计算机的计算机上,运行会ConsoleApplication1.exe导致程序崩溃,并且以下内容将打印到控制台:
C:\test>dir
Volume in drive C has no label.
Volume Serial Number is 7C46-414F
Directory of C:\test
07/12/2010 06:08 PM <DIR> .
07/12/2010 06:08 PM <DIR> ..
07/12/2010 05:13 PM 11,776 ClassLibrary1.dll
07/12/2010 05:13 PM 30,208 ClassLibrary1.pdb
07/12/2010 04:55 PM 3,572 ClassLibrary1.tlb
19/11/2010 02:46 PM 235,008 clipper.dll
19/11/2010 02:46 PM 1,534,976 clipper.pdb
07/12/2010 05:13 PM 6,144 ConsoleApplication1.exe
07/12/2010 05:13 PM 11,776 ConsoleApplication1.pdb
01/08/2010 12:52 PM 139,264 nunit.core.dll
01/08/2010 …Run Code Online (Sandbox Code Playgroud) 我有这个
function(array<Object^>^ a)
Run Code Online (Sandbox Code Playgroud)
我怎么知道这个数组的长度?像C++一样,大小必须附带功能吗?
谢谢,
我这样做了吗?
我得到一个指向本机数组的指针,需要复制到托管数组.将memcpy()与pin_ptr一起使用.
unsigned char* pArray;
unsigned int arrayCount;
// get pArray & arrayCount (from a COM method)
ManagedClass->ByteArray = gcnew array<Byte,1>(arrayCount)
pin_ptr<System::Byte> pinPtrArray = &ManagedClass->ByteArray[0];
memcpy_s(pinPtrArray, arrayCount, pArray, arrayCount);
Run Code Online (Sandbox Code Playgroud)
arrayCount是pArray的实际长度,因此并不担心这个方面.查看代码并从向量中复制数组.所以我可以安全地设置托管数组大小.
为什么我不能为托管类型或泛型函数的成员函数声明默认参数?C# 4.0引入了命名和可选参数 ; 还有类似的东西CLI吗?
我不明白为什么不可能声明这样的方法:
void Optional(int argument = 0);
Run Code Online (Sandbox Code Playgroud)
然后,当我打电话Optional();,编译器不翻译此电话为:Optional(0);.
我正在开发一种可以解释和使用API蓝图的工具.
我创建了一个新的控制台应用程序,添加了SnowCrash.NET nuget包并编写了这段代码:
static void Main(string[] args)
{
snowcrashCLR.Blueprint blueprint;
snowcrashCLR.Result result;
var path = args.Length > 1 ? args[1] : @"c:\";
snowcrashCLR.SnowCrashCLR.parse(path, out blueprint, out result);
if (result != null)
{
var warnings = result.GetWarningsCs();
foreach (var warning in warnings)
{
Console.WriteLine("{0}: {1}", warning.code, warning.message);
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我将代码(复制bin文件夹)部署到与开发环境不同的计算机时,我收到指向SnowCrash.dll的FileNotFoundException
这是一个来自错误消息的snapshop:
无法加载文件或程序集"snowcrashCLR.DLL"或其依赖项之一.指定的模块无法找到.
[FileNotFoundException: Could not load file or assembly 'snowcrashCLR.DLL' or one of its dependencies. The specified module could not be found.]
System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String …Run Code Online (Sandbox Code Playgroud) 我理解在.NET中,即使对象是部分构造的(例如,如果从构造函数中抛出异常),终结器也会运行,但是什么时候构造函数从未运行过呢?
背景
我有一些C++/CLI代码可以有效地执行以下操作(我不相信这是特定于C++/CLI,但这是我已经准备好的情况):
try {
ClassA ^objA = FunctionThatReturnsAClassA();
ClassB ^objB = gcnew ClassB(objA); // ClassB is written in C# in a referenced project
...
}
catch (...) {...}
Run Code Online (Sandbox Code Playgroud)
我有一个100%可重复的情况,如果一个异常被抛出FunctionThatReturnsAClassA(),然后一个GC被触发(似乎通过再次运行这个代码可靠地触发,但等待一段时间也有效),ClassB的终结器被调用.
现在,通过跟踪输出,我可以确认ClassB的构造函数没有运行(这当然是你所期望的).所以不知何故,objB显然被分配并添加到终结器列表中,之后甚至满足调用其构造函数的前提条件(即从FunctionThatReturnsAClassA()收集结果).
这只发生在调试器外部运行的优化版本中.我可以进行各种小的更改,导致终结器没有运行 - 例如在两个语句之间插入另一个方法调用,或者(据说,我认为)将"gcnew ClassB"移动到一个单独的函数中,该函数返回宾语.
在我看来,gcnew语句的分配部分在某种程度上被重新排序并在前一个语句之前运行,但是这个重新排序没有反映在生成的MSIL代码中(打败了我最初的假设,这只是另一个C++/CLI代码gen bug ).此外,将"错误"状态与任何"固定"状态之间生成的MSIL代码进行比较,显示没有意外的结构变化.
我已经在调试器中查看了生成的x86代码,到目前为止它看起来并不奇怪,但我没有深入分析它,无论如何我无法在调试器中重现这种行为所以我不是100%确保我从调试器获得的代码与显示奇怪行为的代码相同.
所以它可能是一个MSIL-> x86代码的基本怪癖,或者它可能是一个处理器指令重新排序(前者似乎更有可能但我没有通过在行为发生时更加努力地获取内存中的确切代码来证实 - 这是我的下一步).
题
因此,在.NET中对象的分配是否与该对象的构造函数调用分开并重新排序是有效的(因为缺少一个更好的术语)?