簡體   English   中英

具有嵌套結構數組的 PInvoke 結構

[英]PInvoke struct with nested struct array

我正在嘗試 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看起來很可疑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM