MySQL NDB API访问违规异常
MySQL NDB API AccessViolationException
我面临一个有趣的问题,这个问题只发生在Windows上,而在Linux/Mono上一切都很好。我已经围绕MySQL集群NDB API库构建了一个C++包装器,我通过P/Invoke从C#代码调用它。到目前为止,我有三种方法:
- 初始化环境并返回句柄的
init()
read()
,它使用句柄从数据库中读取数据- 释放资源的
release()
init()
在每个设置中都工作良好。然而,read()
抛出AccessViolationException
,但仅在Windows上,并且仅在一个线程中调用init()
而在另一个线程调用read()
的情况下抛出。如果我们把每件事都放在一个线程中,那就行了!任何关于可能原因的想法都将不胜感激。
更新12/4/2016-在一个简单的C++测试程序中也注意到了同样的行为,其中init()
在一个线程中调用,read()
在另一个线程调用。因此,该错误与C#/C++互操作无关,而是NDB API库中可以在此处下载的内容(lib
文件夹、mysqlclient.lib
和ndbclient_static.lib
)。
C#代码:
private const string ndbapi = "ndb";
[DllImport(ndbapi)]
public extern static IntPtr init(IntPtr conn_string);
[DllImport(ndbapi)]
public extern static void read(IntPtr ndb_cluster_conn);
[DllImport(ndbapi)]
public extern static void release(IntPtr ndb_cluster_conn, IntPtr char_arr_ptr);
private static IntPtr handle;
private static void InitNdb() {
unsafe {
fixed (byte* conn_buf = Encoding.UTF8.GetBytes("node1:1186")) {
handle = ndb_api_init(new IntPtr(conn_buf));
}
}
}
static void Main(string[] args) {
Thread t = new Thread(InitNdb);// IF I CALL InitNDB IN THE SAME THREAD, EVERYTHING WORKS
t.Start();
.. //waiting for Thread t to complete...
IntPtr bytes_read = read(handle);
...
}
C++代码:(基于官方文档中的示例):
#if defined(WIN32)
#define DLLEXPORT __declspec(dllexport)
#define CALLCV __stdcall
#else
#define DLLEXPORT __attribute__((visibility("default")))
#define CALLCV __attribute__((cdecl))
#endif
..
extern "C" DLLEXPORT Ndb_cluster_connection* CALLCV init(char* connection_string) {
ndb_init();
// Object representing the cluster
Ndb_cluster_connection* cluster_connection = new Ndb_cluster_connection(connection_string);
if (cluster_connection->connect(3, 2, 1)) {
std::cout << "Cluster management server not ready,error:" << cluster_connection->get_latest_error_msg() << "n";
exit(-1);
}
if (cluster_connection->wait_until_ready(10, 0) < 0) {
std::cout << "Cluster not ready within 10 secs, error:" << cluster_connection->get_latest_error_msg() << std::endl;
}
return cluster_connection;
}
extern "C" DLLEXPORT char** CALLCV read(Ndb_cluster_connection* cluster_connection) {
Ndb *ndb_obj = new Ndb(cluster_connection, db_name);
if (ndb_obj->init()) {
std::cout << "Error while initializing Ndb " << std::endl;
}
const NdbDictionary::Dictionary* dict = ndb_obj->getDictionary();
const NdbDictionary::Table *table = dict->getTable("table_name"); <-- THIS IS THE LINE THAT THROWS ACCESS VIOLATION EXCEPTION
..
}
在MySQL集群邮件列表的帮助下,我找到了解决这个问题的方法。
如果要在不同于调用ndb_init()
并获得Ndb_cluster_connection
的线程中通过NDB API读取数据,则需要在另一个线程的开头调用mysql_thread_init()
。然而,这不是预期的行为,也没有文档记录,所以我提交了一个bug。
相关文章:
- 未经治疗的异常访问违规写作位置
- C++ 引发异常:访问冲突写入
- 0x80020009 OLE异常访问除0以外的任何数字
- 未处理的异常..访问冲突写入位置
- 存储类对象的C++模板链表-未处理的异常访问冲突读取位置
- C ODBC未经治疗的异常 /访问违规写作位置
- c++BWAPI异常访问违规
- C++Win32,未屏蔽的异常访问违反写入
- 读取位置/使用结构的矢量时发生未处理的异常访问冲突
- 未处理的异常:访问冲突读取位置
- 多个级别的专用和公共异常访问
- 未捕获异常.访问冲突读取位置
- 未处理的异常 - 访问冲突读取位置0x00000000
- 未处理的异常访问违反2D DirectX渲染D2D1.dll
- 使用函数指针C++异常:访问冲突执行位置0x00000000
- 赋值变量时c++未处理异常访问冲突
- 在c++中使用JNI时,c0000005异常(访问冲突)
- c++ std::cin未处理异常:访问冲突写入位置
- QT点击事件内首次出现异常访问违规写入位置
- 使用 int 变量的 C++ 异常访问冲突