VC++2005 (CLI-C++) 中使用Pwlib和Opal时,运行时报错_CrtIsValidHeapPointer问题的解决!!

87 篇文章 2 订阅

在VC++2005中使用Pwlib和Opal库,界面使用WinForm进行开发,编译选项为 /clr

编译、链接都没有问题,但启动程序时,出现运行时错误:





在网上搜了很久,发现很少有人提到该问题的解决办法,后来看到微软的论坛上,有人提出过这个bug,详情请看我的另外一篇文章:

_CrtIsValidHeapPointer
http://www.cnblogs.com/sunrack/articles/588115.html

原来导致该问题的原因是:

The reason why you get this error is that a winforms application has a managed entry point. The initialization of the native global objects is done by the CRT (C RunTime) startup routine. Since in this case there is no CRT startup routine the MyBoard global object fails to initialize correctly.

VC++开发组的人给出了一种折中的办法,

1. Set Linker/Advanced/Entry Point to "" (empty string)
2. Set Linker/System/Subsystem to Not Set

Step 1: Makes sure that the CRT startup code is invoked. This is because, if no entry point is specified, the linker will automatically use mainCRTStartup, which is defined in the CRT libraries. mainCRTStartup will make sure that the global object is initialized correctly.

Step 2: Makes sure that the linker will look for the symbol “main”. The linker looks for “main” because mainCRTStartup calls main() in its body. The default option for a Winforms application is Subsystem:Windows and this makes the linker look for WinMain().

 

//  ManagedWrapper.cpp

//  This code verifies that DllMain is not called by the Loader
//  automatically when linked with /noentry. It also checks some
//  functions that the CRT initializes.

#include 
< windows.h >
#include 
< stdio.h >
#include 
< string .h >
#include 
< stdlib.h >
#include 
< math.h >
#include 
" _vcclrit.h "

#
using   < mscorlib.dll >
using   namespace  System;

public   ref   class  ManagedWrapper 
{
public:
    
static int minitialize() 
    
{
        
int retval = 0;
        
try 
        
{
            __crt_dll_initialize();
        }
 
        
catch(System::Exception^ e) 
        
{
            Console::WriteLine(e);
            retval 
= 1;
        }

        
return retval;
    }


    
static int mterminate() 
    
{
        
int retval = 0;
        
try 
        
{
            __crt_dll_terminate();
        }
 
        
catch(System::Exception^ e) 
        
{
            Console::WriteLine(e);
            retval 
= 1;
        }

        
return retval;
    }

}
;

经过测试,一切OK!!!!

太爽了,终于可以抛开MFC那笨拙的界面开发工具!!
我现在可以充分利用Winform的快速界面开发功能,底层调用Pwli和Opal来开发视频会议了!

呵呵,我已经连续3天没有睡觉了,今晚终于可以做个好梦了!!

好开心!!!  


虽然程序可以正常启动,但是却会在程序显示Winform的同时,出现一个console窗口,很是不爽。

不服输的我,继续到处找资料,查找了几乎网上所有的资源,在微软的官方文档中,该问题被定义为 load lock,即CLI和CRT的初始化死锁问题,
详见 我的另外一篇文章:

Initialization of Mixed Assemblies
http://www.cnblogs.com/sunrack/articles/592408.html

但是在该文档中提到的几种解决方法,经过测试,发现对我的这个问题均无作用。

后来找到在VC++2003中的解决初始化问题的文章,

详见 我的另外一篇文章:

Persisting View State Update, Using Managed Extensions in a DLL
http://www.cnblogs.com/sunrack/articles/593807.html

该文章详细介绍了VC++2003中的臭名昭著的load lock问题,并给出了解决办法,即自己写dll的初始化函数。

感觉到好像有了希望!!


根据文章介绍的另外一篇文章:
详见我的另外一篇文章:

Converting Managed Extensions for C++ Projects from Pure Intermediate Language to Mixed Mode
http://www.cnblogs.com/sunrack/articles/593847.html

我进行了大量测试,最后发现,VC++2005中的load lock问题,确实已经简化了很多,即已经确定化,最后我终于找到了解决方案:

解决方案:

在项目中添加CPP文件,其中定义一个托管类,其成员函数负责手动调用CRT的初始化。

注意,项目中只要有该CPP文件即可,不需要生成对象或者调用其成员函数。

该文件名称为ManagedWrapper.cpp,定义如下:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值