This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new b8b8e45d fix(csharp): fix C api to work under .NET 4.7.2 (#931)
b8b8e45d is described below

commit b8b8e45da15abfbd59f07e7ea7cbdc168ea6cb44
Author: Curt Hagenlocher <[email protected]>
AuthorDate: Mon Jul 24 10:29:53 2023 -0700

    fix(csharp): fix C api to work under .NET 4.7.2 (#931)
    
    Fixes #930.
---
 csharp/src/Apache.Arrow.Adbc/AdbcStatement.cs      |   2 -
 csharp/src/Apache.Arrow.Adbc/C/CAdbcDriver.cs      | 163 ++++-
 .../src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs | 675 +++++++++++++--------
 .../src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs | 170 +++++-
 csharp/src/Apache.Arrow.Adbc/C/CAdbcError.cs       |   7 +-
 csharp/src/Apache.Arrow.Adbc/C/CAdbcPartitions.cs  |   7 +-
 csharp/src/Apache.Arrow.Adbc/C/NativeDelegate.cs   |  12 +-
 csharp/src/Apache.Arrow.Adbc/Interop.cs            |  33 -
 8 files changed, 728 insertions(+), 341 deletions(-)

diff --git a/csharp/src/Apache.Arrow.Adbc/AdbcStatement.cs 
b/csharp/src/Apache.Arrow.Adbc/AdbcStatement.cs
index 4d3f4a98..6d491f35 100644
--- a/csharp/src/Apache.Arrow.Adbc/AdbcStatement.cs
+++ b/csharp/src/Apache.Arrow.Adbc/AdbcStatement.cs
@@ -16,7 +16,6 @@
  */
 
 using System;
-using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using Apache.Arrow.Ipc;
 
@@ -31,7 +30,6 @@ namespace Apache.Arrow.Adbc
     {
         public AdbcStatement()
         {
-
         }
 
         /// <summary>
diff --git a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriver.cs 
b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriver.cs
index 6ab568a6..b432babc 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriver.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriver.cs
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+using System;
 using System.Runtime.InteropServices;
 using Apache.Arrow.C;
 
@@ -52,7 +53,11 @@ namespace Apache.Arrow.Adbc.C
         /// This is an embedded callback to make it easier for the driver
         /// manager and driver to cooperate.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcDriver*, CAdbcError*, 
AdbcStatusCode> release;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcDriver*, CAdbcError*, 
AdbcStatusCode> release;
+#else
+        internal IntPtr release;
+#endif
 
         /// <summary>
         /// Finish setting options and initialize the database.
@@ -60,7 +65,11 @@ namespace Apache.Arrow.Adbc.C
         /// Some drivers may support setting options after initialization
         /// as well.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> DatabaseInit;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> DatabaseInit;
+#else
+        internal IntPtr DatabaseInit;
+#endif
 
         /// <summary>
         /// Allocate a new (but uninitialized) database.
@@ -71,7 +80,11 @@ namespace Apache.Arrow.Adbc.C
         /// the private_data field to point to the newly allocated struct.
         /// This struct should be released when AdbcDatabaseRelease is called.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> DatabaseNew;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> DatabaseNew;
+#else
+        internal IntPtr DatabaseNew;
+#endif
 
         /// <summary>
         /// Set a byte* option.
@@ -80,12 +93,20 @@ namespace Apache.Arrow.Adbc.C
         /// support setting options after initialization as well.
         ///
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcDatabase*, byte*, byte*, 
CAdbcError*, AdbcStatusCode> DatabaseSetOption;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcDatabase*, byte*, byte*, 
CAdbcError*, AdbcStatusCode> DatabaseSetOption;
+#else
+        internal IntPtr DatabaseSetOption;
+#endif
 
         /// <summary>
         /// Destroy this database. No connections may exist.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> DatabaseRelease;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> DatabaseRelease;
+#else
+        internal IntPtr DatabaseRelease;
+#endif
 
         /// <summary>
         /// Commit any pending transactions. Only used if autocommit is
@@ -94,7 +115,11 @@ namespace Apache.Arrow.Adbc.C
         /// Behavior is undefined if this is mixed with SQL transaction
         /// statements.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> ConnectionCommit; // ConnectionFn
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> ConnectionCommit;
+#else
+        internal IntPtr ConnectionCommit;
+#endif
 
         /// <summary>
         /// Get metadata about the database/driver.
@@ -122,7 +147,11 @@ namespace Apache.Arrow.Adbc.C
         /// for ADBC usage.  Drivers/vendors will ignore requests for
         /// unrecognized codes (the row will be omitted from the result).
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, byte*, int, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionGetInfo;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, byte*, int, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionGetInfo;
+#else
+        internal IntPtr ConnectionGetInfo;
+#endif
 
         /// <summary>
         ///  Get a hierarchical view of all catalogs, database schemas,
@@ -151,12 +180,20 @@ namespace Apache.Arrow.Adbc.C
         /// | table_columns            | list<COLUMN_SCHEMA>     |
         /// | table_constraints        | list<CONSTRAINT_SCHEMA> |
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, int, byte*, 
byte*, byte*, byte**, byte*, CArrowArrayStream*, CAdbcError*, AdbcStatusCode> 
ConnectionGetObjects;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, int, byte*, byte*, 
byte*, byte**, byte*, CArrowArrayStream*, CAdbcError*, AdbcStatusCode> 
ConnectionGetObjects;
+#else
+        internal IntPtr ConnectionGetObjects;
+#endif
 
         /// <summary>
         /// Get the Arrow schema of a table.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, byte*, byte*, 
byte*, CArrowSchema*, CAdbcError*, AdbcStatusCode> ConnectionGetTableSchema;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, byte*, byte*, byte*, 
CArrowSchema*, CAdbcError*, AdbcStatusCode> ConnectionGetTableSchema;
+#else
+        internal IntPtr ConnectionGetTableSchema;
+#endif
 
         /// <summary>
         /// Get a list of table types in the database.
@@ -167,7 +204,11 @@ namespace Apache.Arrow.Adbc.C
         /// ---------------|--------------
         /// table_type     | utf8 not null
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionGetTableTypes;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, CArrowArrayStream*, 
CAdbcError*, AdbcStatusCode> ConnectionGetTableTypes;
+#else
+        internal IntPtr ConnectionGetTableTypes;
+#endif
 
         /// <summary>
         /// Finish setting options and initialize the connection.
@@ -175,7 +216,11 @@ namespace Apache.Arrow.Adbc.C
         /// Some drivers may support setting options after initialization
         /// as well.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, CAdbcDatabase*, 
CAdbcError*, AdbcStatusCode> ConnectionInit;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, CAdbcDatabase*, 
CAdbcError*, AdbcStatusCode> ConnectionInit;
+#else
+        internal IntPtr ConnectionInit;
+#endif
 
         /// <summary>
         /// Allocate a new (but uninitialized) connection.
@@ -187,7 +232,11 @@ namespace Apache.Arrow.Adbc.C
         /// This struct should be released when AdbcConnectionRelease is
         /// called.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> ConnectionNew; // ConnectionFn
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> ConnectionNew;
+#else
+        internal IntPtr ConnectionNew;
+#endif
 
         /// <summary>
         /// Set a byte* option.
@@ -195,7 +244,11 @@ namespace Apache.Arrow.Adbc.C
         /// Options may be set before AdbcConnectionInit.  Some  drivers may
         /// support setting options after initialization as well.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, byte*, byte*, 
CAdbcError*, AdbcStatusCode> ConnectionSetOption;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, byte*, byte*, 
CAdbcError*, AdbcStatusCode> ConnectionSetOption;
+#else
+        internal IntPtr ConnectionSetOption;
+#endif
 
         /// <summary>
         /// Construct a statement for a partition of a query. The
@@ -203,12 +256,20 @@ namespace Apache.Arrow.Adbc.C
         ///
         /// A partition can be retrieved from AdbcPartitions.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, byte*, int, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionReadPartition;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, byte*, int, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionReadPartition;
+#else
+        internal IntPtr ConnectionReadPartition;
+#endif
 
         /// <summary>
         /// Destroy this connection.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> ConnectionRelease; // ConnectionFn
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> ConnectionRelease;
+#else
+        internal IntPtr ConnectionRelease;
+#endif
 
         /// <summary>
         /// Roll back any pending transactions. Only used if autocommit is 
disabled.
@@ -216,32 +277,52 @@ namespace Apache.Arrow.Adbc.C
         /// Behavior is undefined if this is mixed with SQL transaction
         /// statements.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> ConnectionRollback; // ConnectionFn
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> ConnectionRollback;
+#else
+        internal IntPtr ConnectionRollback;
+#endif
 
         /// <summary>
         /// Bind Arrow data. This can be used for bulk inserts or prepared
         /// statements.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, CArrowArray*, 
CArrowSchema*, CAdbcError*, AdbcStatusCode> StatementBind;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, CArrowArray*, 
CArrowSchema*, CAdbcError*, AdbcStatusCode> StatementBind;
+#else
+        internal IntPtr StatementBind;
+#endif
 
         /// <summary>
         /// Bind Arrow data. This can be used for bulk inserts or prepared
         /// statements.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> StatementBindStream;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, CArrowArrayStream*, 
CAdbcError*, AdbcStatusCode> StatementBindStream;
+#else
+        internal IntPtr StatementBindStream;
+#endif
 
         /// <summary>
         /// Execute a statement and get the results.
         ///
         /// This invalidates any prior result sets.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, 
CArrowArrayStream*, long*, CAdbcError*, AdbcStatusCode> StatementExecuteQuery;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, CArrowArrayStream*, 
long*, CAdbcError*, AdbcStatusCode> StatementExecuteQuery;
+#else
+        internal IntPtr StatementExecuteQuery;
+#endif
 
         /// <summary>
         /// Execute a statement and get the results as a partitioned result
         /// set.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, CArrowSchema*, 
CAdbcPartitions*, long*, CAdbcError*, AdbcStatusCode> 
StatementExecutePartitions;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, CArrowSchema*, 
CAdbcPartitions*, long*, CAdbcError*, AdbcStatusCode> 
StatementExecutePartitions;
+#else
+        internal IntPtr StatementExecutePartitions;
+#endif
 
         /// <summary>
         /// Get the schema for bound parameters.
@@ -258,7 +339,11 @@ namespace Apache.Arrow.Adbc.C
         ///
         /// This should be called after AdbcStatementPrepare.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, CArrowSchema*, 
CAdbcError*, AdbcStatusCode> StatementGetParameterSchema;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, CArrowSchema*, 
CAdbcError*, AdbcStatusCode> StatementGetParameterSchema;
+#else
+        internal IntPtr StatementGetParameterSchema;
+#endif
 
         /// <summary>
         /// Create a new statement for a given connection.
@@ -269,7 +354,11 @@ namespace Apache.Arrow.Adbc.C
         /// the private_data field to point to the newly allocated struct.
         /// This struct should be released when AdbcStatementRelease is called.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcConnection*, CAdbcStatement*, 
CAdbcError*, AdbcStatusCode> StatementNew;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcConnection*, CAdbcStatement*, 
CAdbcError*, AdbcStatusCode> StatementNew;
+#else
+        internal IntPtr StatementNew;
+#endif
 
         /// <summary>
         /// Turn this statement into a prepared statement to be
@@ -277,17 +366,29 @@ namespace Apache.Arrow.Adbc.C
         ///
         /// This invalidates any prior result sets.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, CAdbcError*, 
AdbcStatusCode> StatementPrepare; // StatementFn
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, CAdbcError*, 
AdbcStatusCode> StatementPrepare;
+#else
+        internal IntPtr StatementPrepare;
+#endif
 
         /// <summary>
         /// Destroy a statement.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, CAdbcError*, 
AdbcStatusCode> StatementRelease; // StatementFn
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, CAdbcError*, 
AdbcStatusCode> StatementRelease;
+#else
+        internal IntPtr StatementRelease;
+#endif
 
         /// <summary>
         /// Set a string option on a statement.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, byte*, byte*, 
CAdbcError*, AdbcStatusCode> StatementSetOption;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, byte*, byte*, 
CAdbcError*, AdbcStatusCode> StatementSetOption;
+#else
+        internal IntPtr StatementSetOption;
+#endif
 
         /// <summary>
         /// Set the SQL query to execute.
@@ -296,7 +397,11 @@ namespace Apache.Arrow.Adbc.C
         /// queries expected to be executed repeatedly, StatementPrepare
         /// the statement first.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, byte*, 
CAdbcError*, AdbcStatusCode> StatementSetSqlQuery;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, byte*, CAdbcError*, 
AdbcStatusCode> StatementSetSqlQuery;
+#else
+        internal IntPtr StatementSetSqlQuery;
+#endif
 
         /// <summary>
         /// Set the Substrait plan to execute.
@@ -305,6 +410,10 @@ namespace Apache.Arrow.Adbc.C
         /// queries expected to be executed repeatedly, AdbcStatementPrepare
         /// the statement first.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcStatement*, byte*, int, 
CAdbcError*, AdbcStatusCode> StatementSetSubstraitPlan;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcStatement*, byte*, int, CAdbcError*, 
AdbcStatusCode> StatementSetSubstraitPlan;
+#else
+        internal IntPtr StatementSetSubstraitPlan;
+#endif
     }
 }
diff --git a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs 
b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs
index 7b6fce67..ed605713 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverExporter.cs
@@ -31,58 +31,141 @@ namespace Apache.Arrow.Adbc.C
 {
     public class CAdbcDriverExporter
     {
-        private unsafe static readonly NativeDelegate<ErrorRelease> 
releaseError = new NativeDelegate<ErrorRelease>(ReleaseError);
-        private unsafe static readonly NativeDelegate<DriverRelease> 
releaseDriver = new NativeDelegate<DriverRelease>(ReleaseDriver);
-
-        private unsafe static readonly NativeDelegate<DatabaseFn> databaseInit 
= new NativeDelegate<DatabaseFn>(InitDatabase);
-        private unsafe static readonly NativeDelegate<DatabaseFn> 
databaseRelease = new NativeDelegate<DatabaseFn>(ReleaseDatabase);
-        private unsafe static readonly NativeDelegate<DatabaseSetOption> 
databaseSetOption = new NativeDelegate<DatabaseSetOption>(SetDatabaseOption);
-
-        private unsafe static readonly NativeDelegate<ConnectionGetObjects> 
connectionGetObjects = new 
NativeDelegate<ConnectionGetObjects>(GetConnectionObjects);
-        private unsafe static readonly 
NativeDelegate<ConnectionGetTableSchema> connectionGetTableSchema = new 
NativeDelegate<ConnectionGetTableSchema>(GetConnectionTableSchema);
-        private unsafe static readonly NativeDelegate<ConnectionGetTableTypes> 
connectionGetTableTypes = new 
NativeDelegate<ConnectionGetTableTypes>(GetConnectionTableTypes);
-        private unsafe static readonly NativeDelegate<ConnectionInit> 
connectionInit = new NativeDelegate<ConnectionInit>(InitConnection);
-        private unsafe static readonly NativeDelegate<ConnectionFn> 
connectionRelease = new NativeDelegate<ConnectionFn>(ReleaseConnection);
-        private unsafe static readonly NativeDelegate<ConnectionGetInfo> 
connectionGetInfo = new NativeDelegate<ConnectionGetInfo>(GetConnectionInfo);
-        private unsafe static readonly NativeDelegate<ConnectionReadPartition> 
connectionReadPartition = new 
NativeDelegate<ConnectionReadPartition>(ReadConnectionPartition);
-        private unsafe static readonly NativeDelegate<ConnectionSetOption> 
connectionSetOption = new 
NativeDelegate<ConnectionSetOption>(SetConnectionOption);
-
-        private unsafe static readonly NativeDelegate<StatementBind> 
statementBind = new NativeDelegate<StatementBind>(BindStatement);
-        private unsafe static readonly NativeDelegate<StatementExecuteQuery> 
statementExecuteQuery = new 
NativeDelegate<StatementExecuteQuery>(ExecuteStatementQuery);
-        private unsafe static readonly NativeDelegate<StatementNew> 
statementNew = new NativeDelegate<StatementNew>(NewStatement);
-        private unsafe static readonly NativeDelegate<StatementFn> 
statementRelease = new NativeDelegate<StatementFn>(ReleaseStatement);
-        private unsafe static readonly NativeDelegate<StatementSetSqlQuery> 
statementSetSqlQuery = new 
NativeDelegate<StatementSetSqlQuery>(SetStatementSqlQuery);
+        internal unsafe delegate void ErrorRelease(CAdbcError* error);
+        private static unsafe readonly NativeDelegate<ErrorRelease> 
s_releaseError = new NativeDelegate<ErrorRelease>(ReleaseError);
+        internal unsafe delegate AdbcStatusCode DatabaseFn(CAdbcDatabase* 
database, CAdbcError* error);
+        internal unsafe delegate AdbcStatusCode ConnectionFn(CAdbcConnection* 
connection, CAdbcError* error);
+
+#if NET5_0_OR_GREATER
+        private static unsafe delegate* unmanaged<CAdbcError*, void> 
ReleaseErrorPtr => (delegate* unmanaged<CAdbcError*, 
void>)s_releaseError.Pointer;
+        private static unsafe delegate* unmanaged<CAdbcDriver*, CAdbcError*, 
AdbcStatusCode> ReleaseDriverPtr => &ReleaseDriver;
+
+        private static unsafe delegate* unmanaged<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> DatabaseInitPtr => &InitDatabase;
+        private static unsafe delegate* unmanaged<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> DatabaseReleasePtr => &ReleaseDatabase;
+        private static unsafe delegate* unmanaged<CAdbcDatabase*, byte*, 
byte*, CAdbcError*, AdbcStatusCode> DatabaseSetOptionPtr => &SetDatabaseOption;
+
+        private static unsafe delegate* unmanaged<CAdbcConnection*, int, 
byte*, byte*, byte*, byte**, byte*, CArrowArrayStream*, CAdbcError*, 
AdbcStatusCode> ConnectionGetObjectsPtr => &GetConnectionObjects;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, byte*, 
byte*, byte*, CArrowSchema*, CAdbcError*, AdbcStatusCode> 
ConnectionGetTableSchemaPtr => &GetConnectionTableSchema;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionGetTableTypesPtr => 
&GetConnectionTableTypes;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CAdbcDatabase*, CAdbcError*, AdbcStatusCode> ConnectionInitPtr => 
&InitConnection;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CAdbcError*, AdbcStatusCode> ConnectionRollbackPtr => &RollbackConnection;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CAdbcError*, AdbcStatusCode> ConnectionCommitPtr => &CommitConnection;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CAdbcError*, AdbcStatusCode> ConnectionReleasePtr => &ReleaseConnection;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, byte*, 
int, CArrowArrayStream*, CAdbcError*, AdbcStatusCode> ConnectionGetInfoPtr => 
&GetConnectionInfo;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, byte*, 
int, CArrowArrayStream*, CAdbcError*, AdbcStatusCode> 
ConnectionReadPartitionPtr => &ReadConnectionPartition;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, byte*, 
byte*, CAdbcError*, AdbcStatusCode> ConnectionSetOptionPtr => 
&SetConnectionOption;
+
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CArrowArray*, CArrowSchema*, CAdbcError*, AdbcStatusCode> StatementBindPtr => 
&BindStatement;
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CArrowArrayStream*, long*, CAdbcError*, AdbcStatusCode> 
StatementExecuteQueryPtr => &ExecuteStatementQuery;
+        private static unsafe delegate* unmanaged<CAdbcConnection*, 
CAdbcStatement*, CAdbcError*, AdbcStatusCode> StatementNewPtr => &NewStatement;
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CAdbcError*, AdbcStatusCode> StatementReleasePtr => &ReleaseStatement;
+        private static unsafe delegate* unmanaged<CAdbcStatement*, 
CAdbcError*, AdbcStatusCode> StatementPreparePtr => &PrepareStatement;
+        private static unsafe delegate* unmanaged<CAdbcStatement*, byte*, 
CAdbcError*, AdbcStatusCode> StatementSetSqlQueryPtr => &SetStatementSqlQuery;
+#else
+        private static IntPtr ReleaseErrorPtr => s_releaseError.Pointer;
+        internal unsafe delegate AdbcStatusCode DriverRelease(CAdbcDriver* 
driver, CAdbcError* error);
+        private static unsafe readonly NativeDelegate<DriverRelease> 
s_releaseDriver = new NativeDelegate<DriverRelease>(ReleaseDriver);
+        private static IntPtr ReleaseDriverPtr => s_releaseDriver.Pointer;
+
+        private static unsafe readonly NativeDelegate<DatabaseFn> 
s_databaseInit = new NativeDelegate<DatabaseFn>(InitDatabase);
+        private static IntPtr DatabaseInitPtr => s_databaseInit.Pointer;
+        private static unsafe readonly NativeDelegate<DatabaseFn> 
s_databaseRelease = new NativeDelegate<DatabaseFn>(ReleaseDatabase);
+        private static IntPtr DatabaseReleasePtr => s_databaseRelease.Pointer;
+        internal unsafe delegate AdbcStatusCode 
DatabaseSetOption(CAdbcDatabase* database, byte* name, byte* value, CAdbcError* 
error);
+        private static unsafe readonly NativeDelegate<DatabaseSetOption> 
s_databaseSetOption = new NativeDelegate<DatabaseSetOption>(SetDatabaseOption);
+        private static IntPtr DatabaseSetOptionPtr => 
s_databaseSetOption.Pointer;
+
+        private unsafe delegate AdbcStatusCode 
ConnectionGetObjects(CAdbcConnection* connection, int depth, byte* catalog, 
byte* db_schema, byte* table_name, byte** table_type, byte* column_name, 
CArrowArrayStream* stream, CAdbcError* error);
+        private static unsafe readonly NativeDelegate<ConnectionGetObjects> 
s_connectionGetObjects = new 
NativeDelegate<ConnectionGetObjects>(GetConnectionObjects);
+        private static IntPtr ConnectionGetObjectsPtr => 
s_connectionGetObjects.Pointer;
+        private unsafe delegate AdbcStatusCode 
ConnectionGetTableSchema(CAdbcConnection* connection, byte* catalog, byte* 
db_schema, byte* table_name, CArrowSchema* schema, CAdbcError* error);
+        private static unsafe readonly 
NativeDelegate<ConnectionGetTableSchema> s_connectionGetTableSchema = new 
NativeDelegate<ConnectionGetTableSchema>(GetConnectionTableSchema);
+        private static IntPtr ConnectionGetTableSchemaPtr => 
s_connectionGetTableSchema.Pointer;
+        private unsafe delegate AdbcStatusCode 
ConnectionGetTableTypes(CAdbcConnection* connection, CArrowArrayStream* stream, 
CAdbcError* error);
+        private static unsafe readonly NativeDelegate<ConnectionGetTableTypes> 
s_connectionGetTableTypes = new 
NativeDelegate<ConnectionGetTableTypes>(GetConnectionTableTypes);
+        private static IntPtr ConnectionGetTableTypesPtr => 
s_connectionGetTableTypes.Pointer;
+        internal unsafe delegate AdbcStatusCode 
ConnectionInit(CAdbcConnection* connection, CAdbcDatabase* database, 
CAdbcError* error);
+        private static unsafe readonly NativeDelegate<ConnectionInit> 
s_connectionInit = new NativeDelegate<ConnectionInit>(InitConnection);
+        private static IntPtr ConnectionInitPtr => s_connectionInit.Pointer;
+        private static unsafe readonly NativeDelegate<ConnectionFn> 
s_connectionRollback = new NativeDelegate<ConnectionFn>(RollbackConnection);
+        private static IntPtr ConnectionRollbackPtr => 
s_connectionRollback.Pointer;
+        private static unsafe readonly NativeDelegate<ConnectionFn> 
s_connectionCommit = new NativeDelegate<ConnectionFn>(CommitConnection);
+        private static IntPtr ConnectionCommitPtr => 
s_connectionCommit.Pointer;
+        private static unsafe readonly NativeDelegate<ConnectionFn> 
s_connectionRelease = new NativeDelegate<ConnectionFn>(ReleaseConnection);
+        private static IntPtr ConnectionReleasePtr => 
s_connectionRelease.Pointer;
+        private unsafe delegate AdbcStatusCode 
ConnectionGetInfo(CAdbcConnection* connection, byte* info_codes, int 
info_codes_length, CArrowArrayStream* stream, CAdbcError* error);
+        private static unsafe readonly NativeDelegate<ConnectionGetInfo> 
s_connectionGetInfo = new NativeDelegate<ConnectionGetInfo>(GetConnectionInfo);
+        private static IntPtr ConnectionGetInfoPtr => 
s_connectionGetInfo.Pointer;
+        private unsafe delegate AdbcStatusCode 
ConnectionReadPartition(CAdbcConnection* connection, byte* 
serialized_partition, int serialized_length, CArrowArrayStream* stream, 
CAdbcError* error);
+        private static unsafe readonly NativeDelegate<ConnectionReadPartition> 
s_connectionReadPartition = new 
NativeDelegate<ConnectionReadPartition>(ReadConnectionPartition);
+        private static IntPtr ConnectionReadPartitionPtr => 
s_connectionReadPartition.Pointer;
+        internal unsafe delegate AdbcStatusCode 
ConnectionSetOption(CAdbcConnection* connection, byte* name, byte* value, 
CAdbcError* error);
+        private static unsafe readonly NativeDelegate<ConnectionSetOption> 
s_connectionSetOption = new 
NativeDelegate<ConnectionSetOption>(SetConnectionOption);
+        private static IntPtr ConnectionSetOptionPtr => 
s_connectionSetOption.Pointer;
+
+        private unsafe delegate AdbcStatusCode StatementBind(CAdbcStatement* 
statement, CArrowArray* array, CArrowSchema* schema, CAdbcError* error);
+        private static unsafe readonly NativeDelegate<StatementBind> 
s_statementBind = new NativeDelegate<StatementBind>(BindStatement);
+        private static IntPtr StatementBindPtr => s_statementBind.Pointer;
+        internal unsafe delegate AdbcStatusCode 
StatementExecuteQuery(CAdbcStatement* statement, CArrowArrayStream* stream, 
long* rows, CAdbcError* error);
+        private static unsafe readonly NativeDelegate<StatementExecuteQuery> 
s_statementExecuteQuery = new 
NativeDelegate<StatementExecuteQuery>(ExecuteStatementQuery);
+        private static IntPtr StatementExecuteQueryPtr = 
s_statementExecuteQuery.Pointer;
+        internal unsafe delegate AdbcStatusCode StatementNew(CAdbcConnection* 
connection, CAdbcStatement* statement, CAdbcError* error);
+        private static unsafe readonly NativeDelegate<StatementNew> 
s_statementNew = new NativeDelegate<StatementNew>(NewStatement);
+        private static IntPtr StatementNewPtr => s_statementNew.Pointer;
+        internal unsafe delegate AdbcStatusCode StatementFn(CAdbcStatement* 
statement, CAdbcError* error);
+        private static unsafe readonly NativeDelegate<StatementFn> 
s_statementRelease = new NativeDelegate<StatementFn>(ReleaseStatement);
+        private static IntPtr StatementReleasePtr => 
s_statementRelease.Pointer;
+        private static unsafe readonly NativeDelegate<StatementFn> 
s_statementPrepare = new NativeDelegate<StatementFn>(PrepareStatement);
+        private static IntPtr StatementPreparePtr => 
s_statementRelease.Pointer;
+        internal unsafe delegate AdbcStatusCode 
StatementSetSqlQuery(CAdbcStatement* statement, byte* text, CAdbcError* error);
+        private static unsafe readonly NativeDelegate<StatementSetSqlQuery> 
s_statementSetSqlQuery = new 
NativeDelegate<StatementSetSqlQuery>(SetStatementSqlQuery);
+        private static IntPtr StatementSetSqlQueryPtr = 
s_statementSetSqlQuery.Pointer;
+#endif
+
+/*
+ * Not yet implemented
+
+        unsafe delegate AdbcStatusCode StatementBindStream(CAdbcStatement* 
statement, CArrowArrayStream* stream, CAdbcError* error);
+        unsafe delegate AdbcStatusCode 
StatementExecutePartitions(CAdbcStatement* statement, CArrowSchema* schema, 
CAdbcPartitions* partitions, long* rows_affected, CAdbcError* error);
+        unsafe delegate AdbcStatusCode 
StatementGetParameterSchema(CAdbcStatement* statement, CArrowSchema* schema, 
CAdbcError* error);
+        unsafe delegate AdbcStatusCode 
StatementSetSubstraitPlan(CAdbcStatement statement, byte* plan, int length, 
CAdbcError error);
+*/
 
         public unsafe static AdbcStatusCode AdbcDriverInit(int version, 
CAdbcDriver* nativeDriver, CAdbcError* error, AdbcDriver driver)
         {
             DriverStub stub = new DriverStub(driver);
             GCHandle handle = GCHandle.Alloc(stub);
             nativeDriver->private_data = (void*)GCHandle.ToIntPtr(handle);
-            nativeDriver->release = (delegate* 
unmanaged[Stdcall]<CAdbcDriver*, CAdbcError*, 
AdbcStatusCode>)releaseDriver.Pointer;
-
-            nativeDriver->DatabaseInit = (delegate* 
unmanaged[Stdcall]<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode>)databaseInit.Pointer;
-            nativeDriver->DatabaseNew = (delegate* 
unmanaged[Stdcall]<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode>)stub.newDatabase.Pointer;
-            nativeDriver->DatabaseSetOption = (delegate* 
unmanaged[Stdcall]<CAdbcDatabase*, byte*, byte*, CAdbcError*, 
AdbcStatusCode>)databaseSetOption.Pointer;
-            nativeDriver->DatabaseRelease = (delegate* 
unmanaged[Stdcall]<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode>)databaseRelease.Pointer;
-
-            nativeDriver->ConnectionCommit = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode>)connectionRelease.Pointer;
-            nativeDriver->ConnectionGetInfo = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, byte*, int, CArrowArrayStream*, 
CAdbcError*, AdbcStatusCode>)connectionGetInfo.Pointer;
-            nativeDriver->ConnectionGetObjects = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, int, byte*, byte*, byte*, byte**, byte*, 
CArrowArrayStream*, CAdbcError*, AdbcStatusCode>)connectionGetObjects.Pointer;
-            nativeDriver->ConnectionGetTableSchema = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, byte*, byte*, byte*, CArrowSchema*, 
CAdbcError*, AdbcStatusCode>)connectionGetTableSchema.Pointer;
-            nativeDriver->ConnectionGetTableTypes = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CArrowArrayStream*, CAdbcError*, 
AdbcStatusCode>)connectionGetTableTypes.Pointer;
-            nativeDriver->ConnectionInit = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode>)connectionInit.Pointer;
-            nativeDriver->ConnectionNew = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode>)stub.newConnection.Pointer;
-            nativeDriver->ConnectionSetOption = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, byte*, byte*, CAdbcError*, 
AdbcStatusCode>)connectionSetOption.Pointer;
-            nativeDriver->ConnectionReadPartition = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, byte*, int, CArrowArrayStream*, 
CAdbcError*, AdbcStatusCode>)connectionReadPartition.Pointer;
-            nativeDriver->ConnectionRelease = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode>)connectionRelease.Pointer;
-            nativeDriver->ConnectionRollback = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode>)connectionRelease.Pointer;
-
-            nativeDriver->StatementBind = (delegate* 
unmanaged[Stdcall]<CAdbcStatement*, CArrowArray*, CArrowSchema*, CAdbcError*, 
AdbcStatusCode>)statementBind.Pointer;
-            nativeDriver->StatementNew = (delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcStatement*, CAdbcError*, 
AdbcStatusCode>)statementNew.Pointer;
-            nativeDriver->StatementSetSqlQuery = (delegate* 
unmanaged[Stdcall]<CAdbcStatement*, byte*, CAdbcError*, 
AdbcStatusCode>)statementSetSqlQuery.Pointer;
-            nativeDriver->StatementExecuteQuery = (delegate* 
unmanaged[Stdcall]<CAdbcStatement*, CArrowArrayStream*, long*, CAdbcError*, 
AdbcStatusCode>)statementExecuteQuery.Pointer;
-            nativeDriver->StatementPrepare = (delegate* 
unmanaged[Stdcall]<CAdbcStatement*, CAdbcError*, 
AdbcStatusCode>)statementRelease.Pointer;
-            nativeDriver->StatementRelease = (delegate* 
unmanaged[Stdcall]<CAdbcStatement*, CAdbcError*, 
AdbcStatusCode>)statementRelease.Pointer;
+            nativeDriver->release = ReleaseDriverPtr;
+
+            nativeDriver->DatabaseInit = DatabaseInitPtr;
+            nativeDriver->DatabaseNew = stub.NewDatabasePtr;
+            nativeDriver->DatabaseSetOption = DatabaseSetOptionPtr;
+            nativeDriver->DatabaseRelease = DatabaseReleasePtr;
+
+            // TODO: This should probably only set the pointers for the 
functionality actually supported by this particular driver
+            nativeDriver->ConnectionCommit = ConnectionCommitPtr;
+            nativeDriver->ConnectionGetInfo = ConnectionGetInfoPtr;
+            nativeDriver->ConnectionGetObjects = ConnectionGetObjectsPtr;
+            nativeDriver->ConnectionGetTableSchema = 
ConnectionGetTableSchemaPtr;
+            nativeDriver->ConnectionGetTableTypes = ConnectionGetTableTypesPtr;
+            nativeDriver->ConnectionInit = ConnectionInitPtr;
+            nativeDriver->ConnectionNew = stub.NewConnectionPtr;
+            nativeDriver->ConnectionSetOption = ConnectionSetOptionPtr;
+            nativeDriver->ConnectionReadPartition = ConnectionReadPartitionPtr;
+            nativeDriver->ConnectionRelease = ConnectionReleasePtr;
+            nativeDriver->ConnectionRollback = ConnectionRollbackPtr;
+
+            nativeDriver->StatementBind = StatementBindPtr;
+            // nativeDriver->StatementBindStream = StatementBindStreamPtr;
+            nativeDriver->StatementExecuteQuery = StatementExecuteQueryPtr;
+            // nativeDriver->StatementExecutePartitions = 
StatementExecutePartitionsPtr;
+            // nativeDriver->StatementGetParameterSchema = 
StatementGetParameterSchemaPtr;
+            nativeDriver->StatementNew = StatementNewPtr;
+            nativeDriver->StatementPrepare = StatementPreparePtr;
+            nativeDriver->StatementRelease = StatementReleasePtr;
+            nativeDriver->StatementSetSqlQuery = StatementSetSqlQueryPtr;
+            // nativeDriver->StatementSetSubstraitPlan = 
StatementSetSubstraitPlanPtr;
 
             return 0;
         }
@@ -100,7 +183,7 @@ namespace Apache.Arrow.Adbc.C
             ReleaseError(error);
 
 #if NETSTANDARD
-                error->message = 
(byte*)MarshalExtensions.StringToCoTaskMemUTF8(exception.Message);
+            error->message = 
(byte*)MarshalExtensions.StringToCoTaskMemUTF8(exception.Message);
 #else
             error->message = 
(byte*)Marshal.StringToCoTaskMemUTF8(exception.Message);
 #endif
@@ -111,7 +194,7 @@ namespace Apache.Arrow.Adbc.C
             error->sqlstate3 = (byte)0;
             error->sqlstate4 = (byte)0;
             error->vendor_code = 0;
-            error->release = (delegate* unmanaged[Stdcall]<CAdbcError*, 
void>)releaseError.Pointer;
+            error->release = ReleaseErrorPtr;
 
             return AdbcStatusCode.UnknownError;
         }
@@ -188,6 +271,9 @@ namespace Apache.Arrow.Adbc.C
             p = IntPtr.Zero;
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode ReleaseDriver(CAdbcDriver* 
nativeDriver, CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeDriver->private_data);
@@ -198,6 +284,9 @@ namespace Apache.Arrow.Adbc.C
             return 0;
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode InitDatabase(CAdbcDatabase* 
nativeDatabase, CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeDatabase->private_data);
@@ -205,6 +294,9 @@ namespace Apache.Arrow.Adbc.C
             return stub.Init(ref *error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode ReleaseDatabase(CAdbcDatabase* 
nativeDatabase, CAdbcError* error)
         {
             if (nativeDatabase->private_data == null)
@@ -220,6 +312,9 @@ namespace Apache.Arrow.Adbc.C
             return AdbcStatusCode.Success;
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
SetConnectionOption(CAdbcConnection* nativeConnection, byte* name, byte* value, 
CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeConnection->private_data);
@@ -227,6 +322,9 @@ namespace Apache.Arrow.Adbc.C
             return stub.SetOption(name, value, ref *error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode SetDatabaseOption(CAdbcDatabase* 
nativeDatabase, byte* name, byte* value, CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeDatabase->private_data);
@@ -235,6 +333,9 @@ namespace Apache.Arrow.Adbc.C
             return stub.SetOption(name, value, ref *error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode InitConnection(CAdbcConnection* 
nativeConnection, CAdbcDatabase* database, CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeConnection->private_data);
@@ -243,6 +344,9 @@ namespace Apache.Arrow.Adbc.C
         }
 
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
GetConnectionObjects(CAdbcConnection* nativeConnection, int depth, byte* 
catalog, byte* db_schema, byte* table_name, byte** table_type, byte* 
column_name, CArrowArrayStream* stream, CAdbcError* error)
         {
             if (nativeConnection->private_data == null)
@@ -255,6 +359,9 @@ namespace Apache.Arrow.Adbc.C
             return stub.GetObjects(ref *nativeConnection, depth, catalog, 
db_schema, table_name, table_type, column_name, stream, ref *error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
GetConnectionTableTypes(CAdbcConnection* nativeConnection, CArrowArrayStream* 
stream, CAdbcError* error)
         {
             if (nativeConnection->private_data == null)
@@ -267,6 +374,9 @@ namespace Apache.Arrow.Adbc.C
             return stub.GetTableTypes(ref *nativeConnection, stream, ref 
*error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
GetConnectionTableSchema(CAdbcConnection* nativeConnection, byte* catalog, 
byte* db_schema, byte* table_name, CArrowSchema* schema, CAdbcError* error)
         {
             if (nativeConnection->private_data == null)
@@ -279,6 +389,41 @@ namespace Apache.Arrow.Adbc.C
             return stub.GetTableSchema(ref *nativeConnection, catalog, 
db_schema, table_name, schema, ref *error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
+        private unsafe static AdbcStatusCode 
RollbackConnection(CAdbcConnection* nativeConnection, CAdbcError* error)
+        {
+            if (nativeConnection->private_data == null)
+            {
+                return AdbcStatusCode.UnknownError;
+            }
+
+            GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeConnection->private_data);
+            ConnectionStub stub = (ConnectionStub)gch.Target;
+            stub.Rollback();
+            return AdbcStatusCode.Success;
+        }
+
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
+        private unsafe static AdbcStatusCode CommitConnection(CAdbcConnection* 
nativeConnection, CAdbcError* error)
+        {
+            if (nativeConnection->private_data == null)
+            {
+                return AdbcStatusCode.UnknownError;
+            }
+
+            GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeConnection->private_data);
+            ConnectionStub stub = (ConnectionStub)gch.Target;
+            stub.Commit();
+            return AdbcStatusCode.Success;
+        }
+
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
ReleaseConnection(CAdbcConnection* nativeConnection, CAdbcError* error)
         {
             if (nativeConnection->private_data == null)
@@ -294,6 +439,9 @@ namespace Apache.Arrow.Adbc.C
             return AdbcStatusCode.Success;
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
ReadConnectionPartition(CAdbcConnection* nativeConnection, byte* 
serialized_partition, int serialized_length, CArrowArrayStream* stream, 
CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeConnection->private_data);
@@ -301,6 +449,9 @@ namespace Apache.Arrow.Adbc.C
             return stub.ReadPartition(ref *nativeConnection, 
serialized_partition, serialized_length, stream, ref *error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
GetConnectionInfo(CAdbcConnection* nativeConnection, byte* info_codes, int 
info_codes_length, CArrowArrayStream* stream, CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeConnection->private_data);
@@ -308,13 +459,16 @@ namespace Apache.Arrow.Adbc.C
             return stub.GetInfo(ref *nativeConnection, info_codes, 
info_codes_length, stream, ref *error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
SetStatementSqlQuery(CAdbcStatement* nativeStatement, byte* text, CAdbcError* 
error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeStatement->private_data);
             AdbcStatement stub = (AdbcStatement)gch.Target;
 
 #if NETSTANDARD
-                stub.SqlQuery = 
MarshalExtensions.PtrToStringUTF8((IntPtr)text);
+            stub.SqlQuery = MarshalExtensions.PtrToStringUTF8((IntPtr)text);
 #else
             stub.SqlQuery = Marshal.PtrToStringUTF8((IntPtr)text);
 #endif
@@ -322,6 +476,9 @@ namespace Apache.Arrow.Adbc.C
             return AdbcStatusCode.Success;
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode BindStatement(CAdbcStatement* 
nativeStatement, CArrowArray* array, CArrowSchema* cschema, CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeStatement->private_data);
@@ -336,6 +493,9 @@ namespace Apache.Arrow.Adbc.C
             return 0;
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode 
ExecuteStatementQuery(CAdbcStatement* nativeStatement, CArrowArrayStream* 
stream, long* rows, CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeStatement->private_data);
@@ -352,6 +512,9 @@ namespace Apache.Arrow.Adbc.C
             return 0;
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode NewStatement(CAdbcConnection* 
nativeConnection, CAdbcStatement* nativeStatement, CAdbcError* error)
         {
             GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeConnection->private_data);
@@ -359,6 +522,9 @@ namespace Apache.Arrow.Adbc.C
             return stub.NewStatement(ref *nativeStatement, ref *error);
         }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
         private unsafe static AdbcStatusCode ReleaseStatement(CAdbcStatement* 
nativeStatement, CAdbcError* error)
         {
             if (nativeStatement->private_data == null)
@@ -373,186 +539,186 @@ namespace Apache.Arrow.Adbc.C
             nativeStatement->private_data = null;
             return AdbcStatusCode.Success;
         }
-    }
 
+#if NET5_0_OR_GREATER
+        [UnmanagedCallersOnly]
+#endif
+        private unsafe static AdbcStatusCode PrepareStatement(CAdbcStatement* 
nativeStatement, CAdbcError* error)
+        {
+            if (nativeStatement->private_data == null)
+            {
+                return AdbcStatusCode.UnknownError;
+            }
 
-    unsafe delegate AdbcStatusCode DriverRelease(CAdbcDriver* driver, 
CAdbcError* error);
+            GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeStatement->private_data);
+            AdbcStatement statement = (AdbcStatement)gch.Target;
+            statement.Prepare();
+            return AdbcStatusCode.Success;
+        }
 
-    unsafe delegate AdbcStatusCode DatabaseFn(CAdbcDatabase* database, 
CAdbcError* error);
-    unsafe delegate AdbcStatusCode DatabaseSetOption(CAdbcDatabase* database, 
byte* name, byte* value, CAdbcError* error);
+        private sealed class DriverStub : IDisposable
+        {
+            private readonly AdbcDriver _driver;
+            private unsafe readonly NativeDelegate<DatabaseFn> newDatabase;
+            private unsafe readonly NativeDelegate<ConnectionFn> newConnection;
 
-    unsafe delegate AdbcStatusCode ConnectionFn(CAdbcConnection* connection, 
CAdbcError* error);
-    unsafe delegate AdbcStatusCode ConnectionGetInfo(CAdbcConnection* 
connection, byte* info_codes, int info_codes_length, CArrowArrayStream* stream, 
CAdbcError* error);
-    unsafe delegate AdbcStatusCode ConnectionGetObjects(CAdbcConnection* 
connection, int depth, byte* catalog, byte* db_schema, byte* table_name, byte** 
table_type, byte* column_name, CArrowArrayStream* stream, CAdbcError* error);
-    unsafe delegate AdbcStatusCode ConnectionGetTableSchema(CAdbcConnection* 
connection, byte* catalog, byte* db_schema, byte* table_name, CArrowSchema* 
schema, CAdbcError* error);
-    unsafe delegate AdbcStatusCode ConnectionGetTableTypes(CAdbcConnection* 
connection, CArrowArrayStream* stream, CAdbcError* error);
-    unsafe delegate AdbcStatusCode ConnectionInit(CAdbcConnection* connection, 
CAdbcDatabase* database, CAdbcError* error);
-    unsafe delegate AdbcStatusCode ConnectionSetOption(CAdbcConnection* 
connection, byte* name, byte* value, CAdbcError* error);
-    unsafe delegate AdbcStatusCode ConnectionReadPartition(CAdbcConnection* 
connection, byte* serialized_partition, int serialized_length, 
CArrowArrayStream* stream, CAdbcError* error);
+#if NET5_0_OR_GREATER
+            internal unsafe delegate* unmanaged<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> NewDatabasePtr =>
+                (delegate* unmanaged<CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode>)newDatabase.Pointer;
+            internal unsafe delegate* unmanaged<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode> NewConnectionPtr =>
+                (delegate* unmanaged<CAdbcConnection*, CAdbcError*, 
AdbcStatusCode>)newConnection.Pointer;
+#else
+            internal IntPtr NewDatabasePtr => newDatabase.Pointer;
+            internal IntPtr NewConnectionPtr => newConnection.Pointer;
+#endif
 
-    unsafe delegate AdbcStatusCode StatementBind(CAdbcStatement* statement, 
CArrowArray* array, CArrowSchema* schema, CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementBindStream(CAdbcStatement* 
statement, CArrowArrayStream* stream, CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementExecuteQuery(CAdbcStatement* 
statement, CArrowArrayStream* stream, long* rows, CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementExecutePartitions(CAdbcStatement* 
statement, CArrowSchema* schema, CAdbcPartitions* partitions, long* 
rows_affected, CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementGetParameterSchema(CAdbcStatement* 
statement, CArrowSchema* schema, CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementNew(CAdbcConnection* connection, 
CAdbcStatement* statement, CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementFn(CAdbcStatement* statement, 
CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementSetOption(CAdbcStatement* 
statement, byte* name, byte* value, CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementSetSqlQuery(CAdbcStatement* 
statement, byte* text, CAdbcError* error);
-    unsafe delegate AdbcStatusCode StatementSetSubstraitPlan(CAdbcStatement 
statement, byte* plan, int length, CAdbcError error);
+            public DriverStub(AdbcDriver driver)
+            {
+                _driver = driver;
 
-    unsafe delegate void ErrorRelease(CAdbcError* error);
+                unsafe
+                {
+                    newDatabase = new NativeDelegate<DatabaseFn>(NewDatabase);
+                    newConnection = new 
NativeDelegate<ConnectionFn>(NewConnection);
+                }
+            }
 
-    sealed class DriverStub : IDisposable
-    {
-        readonly AdbcDriver _driver;
-        public unsafe readonly NativeDelegate<DatabaseFn> newDatabase;
-        public unsafe readonly NativeDelegate<ConnectionFn> newConnection;
+            private unsafe AdbcStatusCode NewDatabase(CAdbcDatabase* 
nativeDatabase, CAdbcError* error)
+            {
+                if (nativeDatabase->private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
 
-        public DriverStub(AdbcDriver driver)
-        {
-            _driver = driver;
+                DatabaseStub stub = new DatabaseStub(_driver);
+                GCHandle handle = GCHandle.Alloc(stub);
+                nativeDatabase->private_data = 
(void*)GCHandle.ToIntPtr(handle);
 
-            unsafe
-            {
-                newDatabase = new NativeDelegate<DatabaseFn>(NewDatabase);
-                newConnection = new 
NativeDelegate<ConnectionFn>(NewConnection);
+                return AdbcStatusCode.Success;
             }
-        }
 
-        public unsafe AdbcStatusCode NewDatabase(CAdbcDatabase* 
nativeDatabase, CAdbcError* error)
-        {
-            if (nativeDatabase->private_data == null)
+            private unsafe AdbcStatusCode NewConnection(CAdbcConnection* 
nativeConnection, CAdbcError* error)
             {
-                return AdbcStatusCode.UnknownError;
-            }
+                if (nativeConnection->private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
 
-            DatabaseStub stub = new DatabaseStub(_driver);
-            GCHandle handle = GCHandle.Alloc(stub);
-            nativeDatabase->private_data = (void*)GCHandle.ToIntPtr(handle);
+                ConnectionStub stub = new ConnectionStub(_driver);
+                GCHandle handle = GCHandle.Alloc(stub);
+                nativeConnection->private_data = 
(void*)GCHandle.ToIntPtr(handle);
 
-            return AdbcStatusCode.Success;
-        }
+                return AdbcStatusCode.Success;
+            }
 
-        public unsafe AdbcStatusCode NewConnection(CAdbcConnection* 
nativeConnection, CAdbcError* error)
-        {
-            if (nativeConnection->private_data == null)
+            public void Dispose()
             {
-                return AdbcStatusCode.UnknownError;
+                _driver.Dispose();
             }
-
-            ConnectionStub stub = new ConnectionStub(_driver);
-            GCHandle handle = GCHandle.Alloc(stub);
-            nativeConnection->private_data = (void*)GCHandle.ToIntPtr(handle);
-
-            return AdbcStatusCode.Success;
-        }
-
-        public void Dispose()
-        {
-            _driver.Dispose();
         }
-    }
-
-    sealed class DatabaseStub : IDisposable
-    {
-        readonly AdbcDriver _driver;
-        readonly Dictionary<string, string> options;
-        AdbcDatabase database;
 
-        public DatabaseStub(AdbcDriver driver)
+        sealed class DatabaseStub : IDisposable
         {
-            _driver = driver;
-            options = new Dictionary<string, string>();
-        }
+            readonly AdbcDriver _driver;
+            readonly Dictionary<string, string> options;
+            AdbcDatabase database;
 
-        public AdbcStatusCode Init(ref CAdbcError error)
-        {
-            if (database != null)
+            public DatabaseStub(AdbcDriver driver)
             {
-                return AdbcStatusCode.UnknownError;
+                _driver = driver;
+                options = new Dictionary<string, string>();
             }
 
-            database = _driver.Open(options);
-            return AdbcStatusCode.Success;
-        }
+            public AdbcStatusCode Init(ref CAdbcError error)
+            {
+                if (database != null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
 
-        public unsafe AdbcStatusCode SetOption(byte* name, byte* value, ref 
CAdbcError error)
-        {
-            IntPtr namePtr = (IntPtr)name;
-            IntPtr valuePtr = (IntPtr)value;
+                database = _driver.Open(options);
+                return AdbcStatusCode.Success;
+            }
+
+            public unsafe AdbcStatusCode SetOption(byte* name, byte* value, 
ref CAdbcError error)
+            {
+                IntPtr namePtr = (IntPtr)name;
+                IntPtr valuePtr = (IntPtr)value;
 
 #if NETSTANDARD
                 options[MarshalExtensions.PtrToStringUTF8(namePtr)] = 
MarshalExtensions.PtrToStringUTF8(valuePtr);
 #else
-            options[Marshal.PtrToStringUTF8(namePtr)] = 
Marshal.PtrToStringUTF8(valuePtr);
+                options[Marshal.PtrToStringUTF8(namePtr)] = 
Marshal.PtrToStringUTF8(valuePtr);
 #endif
 
-            return AdbcStatusCode.Success;
-        }
+                return AdbcStatusCode.Success;
+            }
 
-        public AdbcStatusCode OpenConnection(IReadOnlyDictionary<string, 
string> options, ref CAdbcError error, out AdbcConnection connection)
-        {
-            if (database == null)
+            public AdbcStatusCode OpenConnection(IReadOnlyDictionary<string, 
string> options, ref CAdbcError error, out AdbcConnection connection)
             {
-                connection = null;
-                return AdbcStatusCode.UnknownError;
+                if (database == null)
+                {
+                    connection = null;
+                    return AdbcStatusCode.UnknownError;
+                }
+
+                connection = database.Connect(options);
+                return AdbcStatusCode.Success;
             }
 
-            connection = database.Connect(options);
-            return AdbcStatusCode.Success;
+            public void Dispose()
+            {
+                database?.Dispose();
+                database = null;
+            }
         }
 
-        public void Dispose()
+        sealed class ConnectionStub : IDisposable
         {
-            database?.Dispose();
-            database = null;
-        }
-    }
+            readonly AdbcDriver _driver;
+            readonly Dictionary<string, string> options;
+            AdbcConnection connection;
 
-    sealed class ConnectionStub : IDisposable
-    {
-        readonly AdbcDriver _driver;
-        readonly Dictionary<string, string> options;
-        AdbcConnection connection;
-
-        public ConnectionStub(AdbcDriver driver)
-        {
-            _driver = driver;
-            options = new Dictionary<string, string>();
-        }
+            public ConnectionStub(AdbcDriver driver)
+            {
+                _driver = driver;
+                options = new Dictionary<string, string>();
+            }
 
-        public unsafe AdbcStatusCode SetOption(byte* name, byte* value, ref 
CAdbcError error)
-        {
-            IntPtr namePtr = (IntPtr)name;
-            IntPtr valuePtr = (IntPtr)value;
+            public unsafe AdbcStatusCode SetOption(byte* name, byte* value, 
ref CAdbcError error)
+            {
+                IntPtr namePtr = (IntPtr)name;
+                IntPtr valuePtr = (IntPtr)value;
 
 #if NETSTANDARD
                 options[MarshalExtensions.PtrToStringUTF8(namePtr)] = 
MarshalExtensions.PtrToStringUTF8(valuePtr);
 #else
-            options[Marshal.PtrToStringUTF8(namePtr)] = 
Marshal.PtrToStringUTF8(valuePtr);
+                options[Marshal.PtrToStringUTF8(namePtr)] = 
Marshal.PtrToStringUTF8(valuePtr);
 #endif
 
-            return AdbcStatusCode.Success;
-        }
+                return AdbcStatusCode.Success;
+            }
 
-        public void Dispose()
-        {
-            connection?.Dispose();
-            connection = null;
-        }
+            public void Rollback() { this.connection.Rollback(); }
+            public void Commit() { this.connection.Commit(); }
 
-        public unsafe AdbcStatusCode GetObjects(ref CAdbcConnection 
nativeConnection, int depth, byte* catalog, byte* db_schema, byte* table_name, 
byte** table_type, byte* column_name, CArrowArrayStream* cstream, ref 
CAdbcError error)
-        {
-            if (nativeConnection.private_data == null)
+            public void Dispose()
             {
-                return AdbcStatusCode.UnknownError;
+                connection?.Dispose();
+                connection = null;
             }
 
-            string catalogPattern = string.Empty;
-            string dbSchemaPattern = string.Empty;
-            string tableNamePattern = string.Empty;
-            string columnNamePattern = string.Empty;
+            public unsafe AdbcStatusCode GetObjects(ref CAdbcConnection 
nativeConnection, int depth, byte* catalog, byte* db_schema, byte* table_name, 
byte** table_type, byte* column_name, CArrowArrayStream* cstream, ref 
CAdbcError error)
+            {
+                if (nativeConnection.private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
+
+                string catalogPattern = string.Empty;
+                string dbSchemaPattern = string.Empty;
+                string tableNamePattern = string.Empty;
+                string columnNamePattern = string.Empty;
 
 #if NETSTANDARD
                 catalogPattern = 
MarshalExtensions.PtrToStringUTF8((IntPtr)catalog);
@@ -560,122 +726,123 @@ namespace Apache.Arrow.Adbc.C
                 tableNamePattern = 
MarshalExtensions.PtrToStringUTF8((IntPtr)table_name);
                 columnNamePattern = 
MarshalExtensions.PtrToStringUTF8((IntPtr)column_name);
 #else
-            catalogPattern = Marshal.PtrToStringUTF8((IntPtr)catalog);
-            dbSchemaPattern = Marshal.PtrToStringUTF8((IntPtr)db_schema);
-            tableNamePattern = Marshal.PtrToStringUTF8((IntPtr)table_name);
-            columnNamePattern = Marshal.PtrToStringUTF8((IntPtr)column_name);
+                catalogPattern = Marshal.PtrToStringUTF8((IntPtr)catalog);
+                dbSchemaPattern = Marshal.PtrToStringUTF8((IntPtr)db_schema);
+                tableNamePattern = Marshal.PtrToStringUTF8((IntPtr)table_name);
+                columnNamePattern = 
Marshal.PtrToStringUTF8((IntPtr)column_name);
 #endif
 
-            GCHandle gch = GCHandle.FromIntPtr((IntPtr)table_type);
-            List<string> tableTypes = (List<string>)gch.Target;
+                GCHandle gch = GCHandle.FromIntPtr((IntPtr)table_type);
+                List<string> tableTypes = (List<string>)gch.Target;
 
-            AdbcConnection.GetObjectsDepth goDepth = 
(AdbcConnection.GetObjectsDepth)depth;
+                AdbcConnection.GetObjectsDepth goDepth = 
(AdbcConnection.GetObjectsDepth)depth;
 
-            IArrowArrayStream stream = connection.GetObjects(goDepth, 
catalogPattern, dbSchemaPattern, tableNamePattern, tableTypes, 
columnNamePattern);
+                IArrowArrayStream stream = connection.GetObjects(goDepth, 
catalogPattern, dbSchemaPattern, tableNamePattern, tableTypes, 
columnNamePattern);
 
-            CArrowArrayStreamExporter.ExportArrayStream(stream, cstream);
+                CArrowArrayStreamExporter.ExportArrayStream(stream, cstream);
 
-            return AdbcStatusCode.Success;
-        }
+                return AdbcStatusCode.Success;
+            }
 
-        public unsafe AdbcStatusCode GetTableSchema(ref CAdbcConnection 
nativeConnection, byte* catalog, byte* db_schema, byte* table_name, 
CArrowSchema* cschema, ref CAdbcError error)
-        {
-            if (nativeConnection.private_data == null)
+            public unsafe AdbcStatusCode GetTableSchema(ref CAdbcConnection 
nativeConnection, byte* catalog, byte* db_schema, byte* table_name, 
CArrowSchema* cschema, ref CAdbcError error)
             {
-                return AdbcStatusCode.UnknownError;
-            }
+                if (nativeConnection.private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
 
-            string sCatalog = string.Empty;
-            string sDbSchema = string.Empty;
-            string sTableName = string.Empty;
+                string sCatalog = string.Empty;
+                string sDbSchema = string.Empty;
+                string sTableName = string.Empty;
 
 #if NETSTANDARD
                 sCatalog = MarshalExtensions.PtrToStringUTF8((IntPtr)catalog);
                 sDbSchema = 
MarshalExtensions.PtrToStringUTF8((IntPtr)db_schema);
                 sTableName = 
MarshalExtensions.PtrToStringUTF8((IntPtr)table_name);
 #else
-            sCatalog = Marshal.PtrToStringUTF8((IntPtr)catalog);
-            sDbSchema = Marshal.PtrToStringUTF8((IntPtr)db_schema);
-            sTableName = Marshal.PtrToStringUTF8((IntPtr)table_name);
+                sCatalog = Marshal.PtrToStringUTF8((IntPtr)catalog);
+                sDbSchema = Marshal.PtrToStringUTF8((IntPtr)db_schema);
+                sTableName = Marshal.PtrToStringUTF8((IntPtr)table_name);
 #endif
 
-            Schema schema = connection.GetTableSchema(sCatalog, sDbSchema, 
sTableName);
+                Schema schema = connection.GetTableSchema(sCatalog, sDbSchema, 
sTableName);
 
-            CArrowSchemaExporter.ExportSchema(schema, cschema);
+                CArrowSchemaExporter.ExportSchema(schema, cschema);
 
-            return AdbcStatusCode.Success;
-        }
-
-        public unsafe AdbcStatusCode GetTableTypes(ref CAdbcConnection 
nativeConnection, CArrowArrayStream* cArrayStream, ref CAdbcError error)
-        {
-            if (nativeConnection.private_data == null)
-            {
-                return AdbcStatusCode.UnknownError;
+                return AdbcStatusCode.Success;
             }
 
-            
CArrowArrayStreamExporter.ExportArrayStream(connection.GetTableTypes(), 
cArrayStream);
+            public unsafe AdbcStatusCode GetTableTypes(ref CAdbcConnection 
nativeConnection, CArrowArrayStream* cArrayStream, ref CAdbcError error)
+            {
+                if (nativeConnection.private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
 
-            return AdbcStatusCode.Success;
-        }
+                
CArrowArrayStreamExporter.ExportArrayStream(connection.GetTableTypes(), 
cArrayStream);
 
-        public unsafe AdbcStatusCode ReadPartition(ref CAdbcConnection 
nativeConnection, byte* serializedPartition, int serialized_length, 
CArrowArrayStream* stream, ref CAdbcError error)
-        {
-            if (nativeConnection.private_data == null)
-            {
-                return AdbcStatusCode.UnknownError;
+                return AdbcStatusCode.Success;
             }
 
-            GCHandle gch = GCHandle.FromIntPtr((IntPtr)serializedPartition);
-            PartitionDescriptor descriptor = (PartitionDescriptor)gch.Target;
+            public unsafe AdbcStatusCode ReadPartition(ref CAdbcConnection 
nativeConnection, byte* serializedPartition, int serialized_length, 
CArrowArrayStream* stream, ref CAdbcError error)
+            {
+                if (nativeConnection.private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
 
-            
CArrowArrayStreamExporter.ExportArrayStream(connection.ReadPartition(descriptor),
 stream);
+                GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)serializedPartition);
+                PartitionDescriptor descriptor = 
(PartitionDescriptor)gch.Target;
 
-            return AdbcStatusCode.Success;
-        }
+                
CArrowArrayStreamExporter.ExportArrayStream(connection.ReadPartition(descriptor),
 stream);
 
-        public unsafe AdbcStatusCode GetInfo(ref CAdbcConnection 
nativeConnection, byte* info_codes, int info_codes_length, CArrowArrayStream* 
stream, ref CAdbcError error)
-        {
-            if (nativeConnection.private_data == null)
-            {
-                return AdbcStatusCode.UnknownError;
+                return AdbcStatusCode.Success;
             }
 
-            GCHandle gch = GCHandle.FromIntPtr((IntPtr)info_codes);
-            List<int> codes = (List<int>)gch.Target;
+            public unsafe AdbcStatusCode GetInfo(ref CAdbcConnection 
nativeConnection, byte* info_codes, int info_codes_length, CArrowArrayStream* 
stream, ref CAdbcError error)
+            {
+                if (nativeConnection.private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
 
-            
CArrowArrayStreamExporter.ExportArrayStream(connection.GetInfo(codes), stream);
+                GCHandle gch = GCHandle.FromIntPtr((IntPtr)info_codes);
+                List<int> codes = (List<int>)gch.Target;
 
-            return AdbcStatusCode.Success;
-        }
+                
CArrowArrayStreamExporter.ExportArrayStream(connection.GetInfo(codes), stream);
 
-        public unsafe AdbcStatusCode InitConnection(ref CAdbcDatabase 
nativeDatabase, ref CAdbcError error)
-        {
-            if (nativeDatabase.private_data == null)
-            {
-                return AdbcStatusCode.UnknownError;
+                return AdbcStatusCode.Success;
             }
 
-            GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeDatabase.private_data);
-            DatabaseStub stub = (DatabaseStub)gch.Target;
-            return stub.OpenConnection(options, ref error, out connection);
-        }
-
-        public unsafe AdbcStatusCode NewStatement(ref CAdbcStatement 
nativeStatement, ref CAdbcError error)
-        {
-            if (connection == null)
+            public unsafe AdbcStatusCode InitConnection(ref CAdbcDatabase 
nativeDatabase, ref CAdbcError error)
             {
-                return AdbcStatusCode.UnknownError;
+                if (nativeDatabase.private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
+
+                GCHandle gch = 
GCHandle.FromIntPtr((IntPtr)nativeDatabase.private_data);
+                DatabaseStub stub = (DatabaseStub)gch.Target;
+                return stub.OpenConnection(options, ref error, out connection);
             }
-            if (nativeStatement.private_data == null)
+
+            public unsafe AdbcStatusCode NewStatement(ref CAdbcStatement 
nativeStatement, ref CAdbcError error)
             {
-                return AdbcStatusCode.UnknownError;
-            }
+                if (connection == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
+                if (nativeStatement.private_data == null)
+                {
+                    return AdbcStatusCode.UnknownError;
+                }
 
-            AdbcStatement statement = connection.CreateStatement();
-            GCHandle handle = GCHandle.Alloc(statement);
-            nativeStatement.private_data = (void*)GCHandle.ToIntPtr(handle);
+                AdbcStatement statement = connection.CreateStatement();
+                GCHandle handle = GCHandle.Alloc(statement);
+                nativeStatement.private_data = 
(void*)GCHandle.ToIntPtr(handle);
 
-            return AdbcStatusCode.Success;
+                return AdbcStatusCode.Success;
+            }
         }
     }
 }
diff --git a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs 
b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs
index 792873e0..fabd1700 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/CAdbcDriverImporter.cs
@@ -130,7 +130,7 @@ namespace Apache.Arrow.Adbc.C
 
             public unsafe override void Dispose()
             {
-                if (_nativeDriver.release != null)
+                if (_nativeDriver.release != default)
                 {
                     using (CallHelper caller = new CallHelper())
                     {
@@ -140,7 +140,7 @@ namespace Apache.Arrow.Adbc.C
                         }
                         finally
                         {
-                            _nativeDriver.release = null;
+                            _nativeDriver.release = default;
                         }
                     }
 
@@ -295,7 +295,8 @@ namespace Apache.Arrow.Adbc.C
                 TranslateCode(init(version, ref driver, ref this._error));
             }
 
-            public unsafe void Call(delegate* unmanaged[Stdcall]<CAdbcDriver*, 
CAdbcError*, AdbcStatusCode> fn, ref CAdbcDriver nativeDriver)
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcDriver*, 
CAdbcError*, AdbcStatusCode> fn, ref CAdbcDriver nativeDriver)
             {
                 fixed (CAdbcDriver* driver = &nativeDriver)
                 fixed (CAdbcError* e = &_error)
@@ -303,8 +304,19 @@ namespace Apache.Arrow.Adbc.C
                     TranslateCode(fn(driver, e));
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcDriver nativeDriver)
+            {
+                fixed (CAdbcDriver* driver = &nativeDriver)
+                fixed (CAdbcError* e = &_error)
+                {
+                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.DriverRelease>(fn)(driver,
 e));
+                }
+            }
+#endif
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcDatabase*, CAdbcError*, AdbcStatusCode> fn, ref 
CAdbcDatabase nativeDatabase)
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcDatabase*, 
CAdbcError*, AdbcStatusCode> fn, ref CAdbcDatabase nativeDatabase)
             {
                 fixed (CAdbcDatabase* db = &nativeDatabase)
                 fixed (CAdbcError* e = &_error)
@@ -312,8 +324,19 @@ namespace Apache.Arrow.Adbc.C
                     TranslateCode(fn(db, e));
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcDatabase 
nativeDatabase)
+            {
+                fixed (CAdbcDatabase* db = &nativeDatabase)
+                fixed (CAdbcError* e = &_error)
+                {
+                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.DatabaseFn>(fn)(db,
 e));
+                }
+            }
+#endif
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcDatabase*, byte*, byte*, CAdbcError*, AdbcStatusCode> 
fn, ref CAdbcDatabase nativeDatabase, string key, string value)
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcDatabase*, byte*, 
byte*, CAdbcError*, AdbcStatusCode> fn, ref CAdbcDatabase nativeDatabase, 
string key, string value)
             {
                 fixed (CAdbcDatabase* db = &nativeDatabase)
                 fixed (CAdbcError* e = &_error)
@@ -331,8 +354,29 @@ namespace Apache.Arrow.Adbc.C
                     }
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcDatabase 
nativeDatabase, string key, string value)
+            {
+                fixed (CAdbcDatabase* db = &nativeDatabase)
+                fixed (CAdbcError* e = &_error)
+                {
+                    using (Utf8Helper utf8Key = new Utf8Helper(key))
+                    using (Utf8Helper utf8Value = new Utf8Helper(value))
+                    {
+                        unsafe
+                        {
+                            IntPtr keyPtr = utf8Key;
+                            IntPtr valuePtr = utf8Value;
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcError*, AdbcStatusCode> fn, ref 
CAdbcConnection nativeConnection)
+                            
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.DatabaseSetOption>(fn)(db,
 (byte*)keyPtr, (byte*)valuePtr, e));
+                        }
+                    }
+                }
+            }
+#endif
+
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcConnection*, 
CAdbcError*, AdbcStatusCode> fn, ref CAdbcConnection nativeConnection)
             {
                 fixed (CAdbcConnection* cn = &nativeConnection)
                 fixed (CAdbcError* e = &_error)
@@ -340,8 +384,19 @@ namespace Apache.Arrow.Adbc.C
                     TranslateCode(fn(cn, e));
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcConnection 
nativeConnection)
+            {
+                fixed (CAdbcConnection* cn = &nativeConnection)
+                fixed (CAdbcError* e = &_error)
+                {
+                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.ConnectionFn>(fn)(cn,
 e));
+                }
+            }
+#endif
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcConnection*, byte*, byte*, CAdbcError*, AdbcStatusCode> 
fn, ref CAdbcConnection nativeConnection, string key, string value)
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcConnection*, 
byte*, byte*, CAdbcError*, AdbcStatusCode> fn, ref CAdbcConnection 
nativeConnection, string key, string value)
             {
                 fixed (CAdbcConnection* cn = &nativeConnection)
                 fixed (CAdbcError* e = &_error)
@@ -359,8 +414,29 @@ namespace Apache.Arrow.Adbc.C
                     }
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcConnection 
nativeConnection, string key, string value)
+            {
+                fixed (CAdbcConnection* cn = &nativeConnection)
+                fixed (CAdbcError* e = &_error)
+                {
+                    using (Utf8Helper utf8Key = new Utf8Helper(key))
+                    using (Utf8Helper utf8Value = new Utf8Helper(value))
+                    {
+                        unsafe
+                        {
+                            IntPtr keyPtr = utf8Key;
+                            IntPtr valuePtr = utf8Value;
+
+                            
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.ConnectionSetOption>(fn)(cn,
 (byte*)keyPtr, (byte*)valuePtr, e));
+                        }
+                    }
+                }
+            }
+#endif
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcDatabase*, CAdbcError*, 
AdbcStatusCode> fn, ref CAdbcConnection nativeConnection, ref CAdbcDatabase 
database)
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcConnection*, 
CAdbcDatabase*, CAdbcError*, AdbcStatusCode> fn, ref CAdbcConnection 
nativeConnection, ref CAdbcDatabase database)
             {
                 fixed (CAdbcConnection* cn = &nativeConnection)
                 fixed (CAdbcDatabase* db = &database)
@@ -369,8 +445,20 @@ namespace Apache.Arrow.Adbc.C
                     TranslateCode(fn(cn, db, e));
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcConnection 
nativeConnection, ref CAdbcDatabase database)
+            {
+                fixed (CAdbcConnection* cn = &nativeConnection)
+                fixed (CAdbcDatabase* db = &database)
+                fixed (CAdbcError* e = &_error)
+                {
+                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.ConnectionInit>(fn)(cn,
 db, e));
+                }
+            }
+#endif
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcConnection*, CAdbcStatement*, CAdbcError*, 
AdbcStatusCode> fn, ref CAdbcConnection nativeConnection, ref CAdbcStatement 
nativeStatement)
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcConnection*, 
CAdbcStatement*, CAdbcError*, AdbcStatusCode> fn, ref CAdbcConnection 
nativeConnection, ref CAdbcStatement nativeStatement)
             {
                 fixed (CAdbcConnection* cn = &nativeConnection)
                 fixed (CAdbcStatement* stmt = &nativeStatement)
@@ -379,8 +467,20 @@ namespace Apache.Arrow.Adbc.C
                     TranslateCode(fn(cn, stmt, e));
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcConnection 
nativeConnection, ref CAdbcStatement nativeStatement)
+            {
+                fixed (CAdbcConnection* cn = &nativeConnection)
+                fixed (CAdbcStatement* stmt = &nativeStatement)
+                fixed (CAdbcError* e = &_error)
+                {
+                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.StatementNew>(fn)(cn,
 stmt, e));
+                }
+            }
+#endif
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcStatement*, CAdbcError*, AdbcStatusCode> fn, ref 
CAdbcStatement nativeStatement)
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcStatement*, 
CAdbcError*, AdbcStatusCode> fn, ref CAdbcStatement nativeStatement)
             {
                 fixed (CAdbcStatement* stmt = &nativeStatement)
                 fixed (CAdbcError* e = &_error)
@@ -388,8 +488,19 @@ namespace Apache.Arrow.Adbc.C
                     TranslateCode(fn(stmt, e));
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcStatement 
nativeStatement)
+            {
+                fixed (CAdbcStatement* stmt = &nativeStatement)
+                fixed (CAdbcError* e = &_error)
+                {
+                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.StatementFn>(fn)(stmt,
 e));
+                }
+            }
+#endif
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcStatement*, byte*, CAdbcError*, AdbcStatusCode> fn, ref 
CAdbcStatement nativeStatement, string sqlQuery)
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcStatement*, 
byte*, CAdbcError*, AdbcStatusCode> fn, ref CAdbcStatement nativeStatement, 
string sqlQuery)
             {
                 fixed (CAdbcStatement* stmt = &nativeStatement)
                 fixed (CAdbcError* e = &_error)
@@ -402,8 +513,24 @@ namespace Apache.Arrow.Adbc.C
                     }
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcStatement 
nativeStatement, string sqlQuery)
+            {
+                fixed (CAdbcStatement* stmt = &nativeStatement)
+                fixed (CAdbcError* e = &_error)
+                {
+                    using (Utf8Helper query = new Utf8Helper(sqlQuery))
+                    {
+                        IntPtr bQuery = (IntPtr)(query);
 
-            public unsafe void Call(delegate* 
unmanaged[Stdcall]<CAdbcStatement*, CArrowArrayStream*, long*, CAdbcError*, 
AdbcStatusCode> fn, ref CAdbcStatement nativeStatement, CArrowArrayStream* 
arrowStream, ref long nRows)
+                        
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.StatementSetSqlQuery>(fn)(stmt,
 (byte*)bQuery, e));
+                    }
+                }
+            }
+#endif
+
+#if NET5_0_OR_GREATER
+            public unsafe void Call(delegate* unmanaged<CAdbcStatement*, 
CArrowArrayStream*, long*, CAdbcError*, AdbcStatusCode> fn, ref CAdbcStatement 
nativeStatement, CArrowArrayStream* arrowStream, ref long nRows)
             {
                 fixed (CAdbcStatement* stmt = &nativeStatement)
                 fixed (long* rows = &nRows)
@@ -412,15 +539,30 @@ namespace Apache.Arrow.Adbc.C
                     TranslateCode(fn(stmt, arrowStream, rows, e));
                 }
             }
+#else
+            public unsafe void Call(IntPtr fn, ref CAdbcStatement 
nativeStatement, CArrowArrayStream* arrowStream, ref long nRows)
+            {
+                fixed (CAdbcStatement* stmt = &nativeStatement)
+                fixed (long* rows = &nRows)
+                fixed (CAdbcError* e = &_error)
+                {
+                    
TranslateCode(Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.StatementExecuteQuery>(fn)(stmt,
 arrowStream, rows, e));
+                }
+            }
+#endif
 
             public unsafe void Dispose()
             {
-                if (_error.release != null)
+                if (_error.release != default)
                 {
                     fixed (CAdbcError* err = &_error)
                     {
+#if NET5_0_OR_GREATER
                         _error.release(err);
-                        _error.release = null;
+#else
+                        
Marshal.GetDelegateForFunctionPointer<CAdbcDriverExporter.ErrorRelease>(err->release)(err);
+#endif
+                        _error.release = default;
                     }
                 }
             }
diff --git a/csharp/src/Apache.Arrow.Adbc/C/CAdbcError.cs 
b/csharp/src/Apache.Arrow.Adbc/C/CAdbcError.cs
index 7b3ddf5f..8cd868ba 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/CAdbcError.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/CAdbcError.cs
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+using System;
 using System.Runtime.InteropServices;
 
 namespace Apache.Arrow.Adbc.C
@@ -86,6 +87,10 @@ namespace Apache.Arrow.Adbc.C
         /// Unlike other structures, this is an embedded callback to make it
         /// easier for the driver manager and driver to cooperate.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcError*, void> release;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcError*, void> release;
+#else
+        internal IntPtr release;
+#endif
     };
 }
diff --git a/csharp/src/Apache.Arrow.Adbc/C/CAdbcPartitions.cs 
b/csharp/src/Apache.Arrow.Adbc/C/CAdbcPartitions.cs
index 23c3e4ab..aee1dc4c 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/CAdbcPartitions.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/CAdbcPartitions.cs
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+using System;
 using System.Runtime.InteropServices;
 
 namespace Apache.Arrow.Adbc.C
@@ -69,6 +70,10 @@ namespace Apache.Arrow.Adbc.C
         /// Unlike other structures, this is an embedded callback to make it
         /// easier for the driver manager and driver to cooperate.
         /// </summary>
-        public delegate* unmanaged[Stdcall]<CAdbcPartitions*, void> release;
+#if NET5_0_OR_GREATER
+        internal delegate* unmanaged<CAdbcPartitions*, void> release;
+#else
+        internal IntPtr release;
+#endif
     }
 }
diff --git a/csharp/src/Apache.Arrow.Adbc/C/NativeDelegate.cs 
b/csharp/src/Apache.Arrow.Adbc/C/NativeDelegate.cs
index c38d8df7..91a9cef2 100644
--- a/csharp/src/Apache.Arrow.Adbc/C/NativeDelegate.cs
+++ b/csharp/src/Apache.Arrow.Adbc/C/NativeDelegate.cs
@@ -20,22 +20,16 @@ using System.Runtime.InteropServices;
 
 namespace Apache.Arrow.Adbc.C
 {
-    internal readonly struct NativeDelegate<T>
+    internal readonly struct NativeDelegate<T> where T : Delegate
     {
         private readonly T _managedDelegate; // For lifetime management
-        private readonly IntPtr _nativePointer;
 
         public NativeDelegate(T managedDelegate)
         {
             _managedDelegate = managedDelegate;
-            _nativePointer = 
Marshal.GetFunctionPointerForDelegate<T>(managedDelegate);
+            Pointer = Marshal.GetFunctionPointerForDelegate(managedDelegate);
         }
 
-        public static implicit operator IntPtr(NativeDelegate<T> thunk)
-        {
-            return thunk._nativePointer;
-        }
-
-        public IntPtr Pointer { get { return _nativePointer; } }
+        public IntPtr Pointer { get; }
     }
 }
diff --git a/csharp/src/Apache.Arrow.Adbc/Interop.cs 
b/csharp/src/Apache.Arrow.Adbc/Interop.cs
deleted file mode 100644
index d21b5bc1..00000000
--- a/csharp/src/Apache.Arrow.Adbc/Interop.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using Apache.Arrow.Adbc.C;
-using Apache.Arrow.C;
-using Apache.Arrow.Ipc;
-
-#if NETSTANDARD
-using Apache.Arrow.Adbc.Extensions;
-#endif
-
-namespace Apache.Arrow.Adbc
-{
-}


Reply via email to