c# - 带有嵌套结构数组的 PInvoke 结构
问题描述
我正在尝试 PInvoke 一个具有嵌套结构数组指针的结构参数的方法。c 声明如下所示:
duckdb_state duckdb_query(duckdb_connection connection, const char *query, duckdb_result *out_result);
typedef struct {
void *data;
bool *nullmask;
duckdb_type type;
char *name;
} duckdb_column;
typedef struct {
idx_t column_count;
idx_t row_count;
duckdb_column *columns;
char *error_message;
} duckdb_result;
我在 C# 中这样声明它们:
[DllImport("duckdb.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "duckdb_query")]
public static extern DuckdbState DuckdbQuery(IntPtr connection, string query, out DuckdbResult result);
[StructLayout(LayoutKind.Sequential)]
public struct DuckdbColumn
{
IntPtr data;
bool nullmask;
DuckdbType type;
string name;
}
[StructLayout(LayoutKind.Sequential)]
public struct DuckdbResult
{
public long column_count;
public long row_count;
public IntPtr columns;
public string error_message;
}
但是当我尝试执行查询并读取列时,我没有得到任何有意义的数据:
result = DuckdbQuery(connection, "SELECT * FROM integers", out queryResult);
DuckdbColumn[] columns = new DuckdbColumn[queryResult.column_count];
var queryResultColumns = queryResult.columns;
var columnPointer = Marshal.ReadIntPtr(queryResultColumns);
var ptrToStructure = (DuckdbColumn)Marshal.PtrToStructure(columnPointer, typeof(DuckdbColumn));
我应该如何更改 PInvoke 声明,以便在执行查询后可以读取列?
在以下位置有示例 c 代码:DuckDB c 示例
更新 1
我可以使用以下代码获取列名:
for (int i = 0; i < queryResult.column_count; i++)
{
var column = (DuckdbColumn)Marshal.PtrToStructure(queryResult.columns + 8 + (Marshal.SizeOf<DuckdbColumn>() + 8) * i, typeof(DuckdbColumn));
columns[i] = column;
}
但type
字段仍然说DUCKDB_TYPE_INVALID
更新 2
正如大卫在他的回答中所建议的那样,我改为bool nullmask;
现在IntPtr nullmask;
可以阅读这样的列信息:
for (int i = 0; i < queryResult.column_count; i++)
{
var column = (DuckdbColumn)Marshal.PtrToStructure(queryResult.columns + Marshal.SizeOf<DuckdbColumn>() * i, typeof(DuckdbColumn));
columns[i] = column;
}
解决方案
您翻译此字段有误
bool *nullmask
这不是一个bool
它是一个指针。将其声明为
IntPtr nullmask;
可能还有其他错误,因为我们看不到所有的翻译。此外,+8
您的数组访问指针算法看起来很可疑。
推荐阅读
- c# - 如何在 wix 中实现安装程序进度条的回滚?
- azure-devops-extensions - 如果任何 AzureDevops 构建代理不可用,如何获得警报?
- c# - 单击按钮时显示 2 个用户输入变量的结果
- python - 在linux中升级python
- c# - c# 获取公共频道 Telegram without Bot Api 和 Telegram Api 的特别帖子
- php - WooCommerce 自定义订单操作不适用于垃圾状态
- azure - 使用 AzureFileCopy 任务覆盖 Azure Blob 存储中的文件
- javascript - 用户事件后的 Wordpress Enqueue 脚本,例如点击
- python - 如何绘制整齐的 ImageGrid 图?
- reactjs - 在单个 Axios POST 请求中发送 FormData 对象和文件