我有一个选择和运行SQL查询的过程。有时(大多数情况下它工作正常)这会导致原始调用函数结束时崩溃。这个过程是这样的(实例化类中的所有方法调用); (注意;由于实际代码是1000行而只列出流程。如果需要,我会尝试提供更多细节)
对QueryPicker的方法调用(params)(c#)
QueryPicker调用cs_query_picker(params)(c ++,在加载的dll中,当时由其他服务共享)
cs_query_picker声明100个变量然后调用QueryPickerWrapper(params)(c#)
QueryPickerWrapper使用gcnew
string ^Params = gcnew string;
if (param != nullptr)
Params->Str = gcnew String (params);
然后, QueryPickerWrapper调用MycinPicker(Params)//用gcnew制作
这将找到SQL查询并运行它。它可能需要长达1200毫秒(真的不是可怕的长)
MyQueryPicker然后设置Params(带有查询结果)并返回true(设置的东西)
QueryPickerWrapper返回true时,设置指针
if(params != nullptr)
strcpy_s(params, PARAM_LEN+1, (char*)(void*)Marshal::StringToHGlobalAnsi(Params->Str));
然后 QueryPickerWrapper返回true
当QueryPickerWrapper获得1时,cs_query_picker返回1,否则它将移动到旧代码(1998年的东西,将使用100个声明的变量)来设置参数。在所有崩溃中,QueryPickerWrapper总是返回1.
QueryPicker接收1,使用传回的参数完成方法,然后崩溃。
我从未在崩溃中遇到过异常(我有一个尝试/捕获它)和Windows事件日志,它说
错误模块名称:clr.dll,版本:4.0.30319.34209
例外代码:0xc00000fd
故障偏移:0x001a149f
据我所知,这是一个堆栈溢出。但是,我不知道它会如何发生。我失败了,因为问题是间歇性的(有时也是每小时,有时不是几天),这是垃圾收集器运行时和返回之前SQL调用的时间之间的关系。
问题: 这是怎么发生的,我该怎么做才能解决它?
这是在.NET4.0中编译和运行的
答案 0 :(得分:0)
string ^Params = gcnew string;
if (param != nullptr)
Params->Str = gcnew String (params);
我无法说出这里的拼写错误,以及可能存在的编码问题。
Params = gcnew string
,然后是Params->Str
。 System::String
和std::string
都没有名为Str
的成员。 Params是一个结构,还是类似的东西?Params
,param
和params
。你有三个几乎同名的变量。如果他们互相打错,那么我不知道params->Str = gcnew String(params);
应该做什么。
strcpy_s(params, PARAM_LEN+1, (char*)(void*)Marshal::StringToHGlobalAnsi(Params->Str));
好的,我可以回答这个问题。你的主要问题是你在StringToHGlobalAnsi
中分配一个新的HGlobal,并且永远不会释放它(内存泄漏)。你可以保持指针并释放它,但我更喜欢使用std::string
作为临时变量。每个人都知道如何处理std::string
,因此没有新的规则需要学习。
#include <msclr/marshal_cppstd.h>
std::string temp = marshal_as<std::string>(source);
strcpy_s(destination, PARAM_LEN+1, temp->c_str());