在C#中如何调用libsqlite3中的返回值为char *的函数

41 篇文章 0 订阅
13 篇文章 0 订阅

之前写了在C#中调用libsqlite3中函数的一些代码:


[DllImport("sqlite3.dll")]  

private extern staticstring sqlite3_column_text(IntPtr pStmt, int iCol); 

[DllImport("sqlite3.dll")]  

privatee xtern static string sqlite3_errmsg(IntPtr pDb);  


public static string Errmsg(IntPtr pDb){

return sqlite3_errmsg(pDb);

}


public static string ColumnText(IntPtr pStmt,int iCol){

return sqlite3_column_text(pStmt, iCol);

}

 

在实际使用Errmsg或ColumnText,发现会产生如下错误:

pointer being freed was not allocated


释放了没分配的内存,怀疑是Marshal对返回的char *进行free搞的鬼。   经google,果然如此:

SQLite manages its own memory, so the char* returned can not be freed by the interop marshaler. The marshaler calls CoTaskMemFree() on every char* that is returned.

So instead of "string", "IntPtr" needs to be used for all returned string pointers.

SQLite returns the string encoded in UTF-8. A direct conversion from a UTF-8 IntPtr to a .NET string is not supported in the Marshal class, but here is an article on how to do the conversion:

http://blog.gebhardtcomputing.com/2007/11/marshal-utf8-strings-in-net.html

And whenever possible, the UTF-16 SQLite functions (suffixed with "16") should be used. To convert the UTF-16 strings from an IntPtr, a simple call to Marshal.PtrToStringUni can be used.

 

sqlite3_column_text和sqlite3_column_text的共同特点是返回值char *,并且返回的char *不能由我们自己释放,返回的char *是用libsqlite3管理的。


因此 正确的调用方法是:

[DllImport("sqlite3.dll")]  

private extern static IntPtr sqlite3_column_text(IntPtr pStmt, int iCol); 

[DllImport("sqlite3.dll")]  

private extern static IntPtr sqlite3_errmsg(IntPtr pDb);  



public static string Errmsg(IntPtr pDb){

IntPtr strPtr = sqlite3_errmsg(pDb);

return Marshal.PtrToStringUni(strPtr);

}


public static string ColumnText(IntPtr pStmt, int iCol){

IntPtr strPtr = sqlite3_column_text(pStmt, iCol);

return Marshal.PtrToStringUni(strPtr);

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值