我已经在本机C ++中编写了一些代码,这些代码调用了blas和lapack库的fortran例程(链接为dll)。本机代码运行正常,没有编译器或运行时错误或警告。
现在,我试图将本机C ++包装到.NET框架中使用的dll中,所以我启动了一个Visual C ++项目,编写了一个包装器ref类,将其编译成一个dll并将该dll包含在C#中项目。
在我最终设法将C#项目编译后,我尝试运行它。但是在第一次调用lapack例程时出现运行时错误! (即在Test.cpp中的dpbtrf_( &LOWER, &n, &izero, D.data(), &ione, &info );
行
错误说:
System.AccessViolationException was unhandled
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=DotNetTest
我错过了一些编译器选项吗? 或者是否存在本机C ++编译器\运行时没有看到的损坏的内存? 关于如何调试这个的任何提示?
非常感谢!
这是一个微小的复制品,它会产生与原始代码相同的问题(这个问题太广泛了,不能在这里发布):
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
#include <vector>
namespace NativeTest
{
class Test
{
public:
Test( int size );
~Test();
void set( int i, double d );
double get( int i ) const;
int chol();
private:
std::vector<double> D;
int n;
}; // class Test
} // namespace NativeTest
#endif // TEST_H_INCLUDED
#include "Test.h"
using namespace NativeTest;
const int ione = 1;
const int izero = 0;
const char LOWER = 'L';
extern "C"
{
// factorization for banded matrix
void __cdecl dpbtrf_( const char *UPLO, const int *N, const int *KD,
double *AB, const int *LDAB, int *INFO );
}
Test::Test( int size ) : n( size )
{ D.resize( n ); }
Test::~Test() { }
void Test::set( int i, double d ) { D[ i ] = d; }
double Test::get( int i ) const { return D[ i ]; }
int Test::chol()
{
int info = 0;
dpbtrf_( &LOWER, &n, &izero, D.data(), &ione, &info );
return info;
}
// TestNet.h
#pragma once
#include "Test.h"
using namespace System;
namespace DotNetTest {
public ref class TestNet
{
public:
TestNet( int size ) { test = new NativeTest::Test( size ); }
~TestNet() { this->!TestNet(); }
!TestNet() { delete test; test = NULL; }
void set( int i, double d ) { test->set( i, d ); }
double get( int i ) { return test->get( i ); }
int chol() { return test->chol(); }
protected:
NativeTest::Test * test;
};
}
DotNetTest.TestNet t = new DotNetTest.TestNet(2);
t.set(0, 2);
t.set(1, 3);
int info = t.chol();
答案 0 :(得分:1)
我修好了,至少对于这里发布的测试代码。我错误地添加了gcc编译的lapack \ blas二进制文件,与我原来的项目(也使用gcc)相同。
今天,我下载了Windows from here的预编译二进制文件,将它们放在我的C#项目的bin文件夹中(连同3个MinGW dll:libgcc_s_dw2-1.dll,libgfortran-3.dll和libquadmath- 0.dll)并确保Visual C ++ \ CLI项目使用相同的库链接(通过将Additional Link Directory设置为C#bin文件夹)。这修复了它,我得到了我想要的结果(没有访问冲突,计算是正确的)。
我还删除了Test.cpp文件的编译选项中的/ clr标志,并关闭该文件的'Use precompiled headers'。