2012-12-09摘要:
我计划使用的实际CLR托管可执行文件与此问题中概述的非常类似,除了一些小的更改:
OPR_FinalizerRun根据Hans Passant的建议设置为某个值(当前为60秒,但可能会发生变化).CLRCreateInstance从mscoree.dll动态(以允许更好的错误消息没有安装兼容CLR时).Main程序集DLL中的指定函数.感谢所有花时间阅读问题和/或评论的人.
2012-12-02帖子底部更新.
我正在使用Visual Studio 2012和.NET 4进行混合模式C++/CLI应用程序,并且惊讶地发现某些本机全局对象的析构函数没有被调用.调查的问题,它原来,他们表现得像管理对象在解释这个职位.
我对此行为感到非常惊讶(我理解它对于托管对象)并且无法在任何地方找到它,无论是在C++/CLI标准中还是在析构函数和终结器的描述中.
根据Hans Passant的评论中的建议,我将程序编译为程序集DLL并将其托管在一个小的本机可执行文件中,这确实给了我所需的行为(析构函数有足够的时间来完成和运行在同一个线程中建造)!
我的问题:
ICLRPolicyManager->SetTimeout(OPR_ProcessExit, INFINITE)为可执行文件配置进程超时策略(即基本上调用)?这将是一个可接受的解决方法.要重现如下编译以下文件:
cl /EHa /MDd CLRHost.cpp
cl /EHa /MDd /c Native.cpp
cl /EHa /MDd /c /clr CLR.cpp
link /out:CLR.exe Native.obj CLR.obj
link /out:CLR.dll /DLL Native.obj CLR.obj
Run Code Online (Sandbox Code Playgroud)
不需要的行为:
C:\Temp\clrhost>clr.exe
[1210] …Run Code Online (Sandbox Code Playgroud) 首先我认为dll DLLMain中的入口点,但是当我尝试在C#中导入它时,我得到一个错误,找不到入口点这是我的代码:
#include <Windows.h>
int Test(int x,int y)
{
return x+y;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(0,L"Test",L"From unmanaged dll",0);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Run Code Online (Sandbox Code Playgroud)
如何为我的dll设置入口点?如果你不介意,你可以给我一些关于切入点的解释吗?
像我必须再次设置导入相同的DLL并更改入口点,以便我可以在同一个DLL中使用其他功能?提前致谢.
以下代码是否在C++中定义良好?(*)
我很难弄清楚在标准中的哪个位置,并且搜索网络并没有发现具体的东西.
struct S;
struct T {
constexpr T() = default;
bool S::* a = nullptr;
int b = 42;
};
const T t{};
// Test. Compiled using: cl /W4 /WX /FAs filename.cpp
#include <stdlib.h>
int main() {
if (t.b != 42) abort();
}
Run Code Online (Sandbox Code Playgroud)
我问的原因是因为它适用于(或似乎)较新版本的GCC和Clang(x86/x86_64),但在Visual Studio 2015 Update 2和Update 3 RC中失败(**).
在报告错误之前,我想确定我不是依赖于未定义的行为,或者只是没有搜索正确的术语.
(*):我主要关心C++ 14及更高版本,但我认为答案不适用于C++ 11.
(**):如果代码定义明确,它看起来像一个codegen bug,它不是指针的分配空间.更改struct S到struct S{}似乎使代码的"工作".
这种声明在c ++中意味着什么?
CSomething & SOMETHING = m_vSOMETHING[m_iSOMETHING];
Run Code Online (Sandbox Code Playgroud) 这是一个确切的问题:
下面的代码转换了M x M数组的元素,其中M是#define定义的常量:
void transpose(Marray_t A) {
int i, j;
for (i = 0; i < M; i++)
for (j = 0; j < i; j++) {
int t = A[i][j];
A[i][j] = A[j][i];
A[j][i] = t;
}
}
Run Code Online (Sandbox Code Playgroud)
当使用优化级别-02进行编译时,GCC会为函数的内部循环生成以下代码:
1. .L3
2. movl (%ebx),%eax
3. movl (%esi,%ecx,4),%edx
4. movl %eax, (%esi,%ecx,4)
5. addl $1, %ecx
6. movl %edx, (%ebx)
7. addl $52,%ebx
8. cmpl %edi,%ecx
9. jl .L3
Run Code Online (Sandbox Code Playgroud)
A. M的价值是多少?
B.什么寄存器保存程序值i和j?
C.编写转置的C代码版本,该版本利用此循环中发生的优化.在代码中使用参数M而不是数字常量.
所以在我试图理解这一点时,我注意到它乘以4,这意味着它存储了4个字节的类型(可能是int或指针).然后,它增加我$ 52(我假设我),因为它是一个更大的值,因此进入下一个数组)和$ 52/4是13.所以我猜M = 13.错了吗?
对于B,我猜想%ebx包含i而%ecx包含i. …
在注册表中有一个(或多个)密钥,具体取决于您拥有的监视器HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\DEL404C\{Some Unique ID}\Device Parameters\EDID数量REG_BINARY key.在我的情况下,这是:
00 FF FF FF FF FF FF 00 10 AC 4C 40 53 43 34 42 34 14 01 03 0A 2F 1E 78 EE EE 95 A3 54
4C 99 26 0F 50 54 A5 4B 00 71 4F 81 80 B3 00 01 01 01 01 01 01 01 01 01 01 21 39 90 30
62 1A 27 40 68 B0 36 00 DA 28 11 00 00 …Run Code Online (Sandbox Code Playgroud)