【发布时间】:2018-03-22 00:57:10
【问题描述】:
鉴于以下由 Kotlin/Native 生成的 C API:
#ifndef KONAN_bar_H
#define KONAN_bar_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
/* Service functions. */
void (*DisposeStablePointer)(bar_KNativePtr ptr);
void (*DisposeString)(const char* string);
bar_KBoolean (*IsInstance)(bar_KNativePtr ref, const bar_KType* type);
/* User functions. */
struct {
struct {
void (*foo)(const char* string);
} root;
} kotlin;
} bar_ExportedSymbols;
extern bar_ExportedSymbols* bar_symbols(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* KONAN_bar_H */
如何使用 P/Invoke 从 C# 访问本机函数 foo?
我一直在经历Marshal API,并尝试了几种不同的方法来编组本机对象(例如从extern 调用返回IntPtr 后的Marshal.PtrToStructure),但我知道我有一个根本的误解关于如何编组本机对象,当给定一个像上面这样的嵌套结构时,事情会变得更加复杂。
我一直在通过this guide 尝试学习如何编组复杂对象,但似乎没有涵盖这个特定的用例。
经过几个小时试图压缩我们的任何东西,这是我的应用程序的当前状态:
public class TestExtern
{
[UnmanagedFunctionPointer( CallingConvention.StdCall )]
public delegate void foo( string @string );
[DllImport( "bar" )]
private static extern BarSymbols bar_symbols();
private void Start()
{
var barSymbols = bar_symbols();
var kotlin = barSymbols.kotlin;
var root = kotlin.root;
var fooDelegate = Marshal.GetDelegateForFunctionPointer<foo>( root.instance );
fooDelegate( "Testing" ); // Access Violation
}
[StructLayout( LayoutKind.Sequential )]
public struct BarSymbols
{
public Kotlin kotlin;
}
[StructLayout( LayoutKind.Sequential )]
public struct Kotlin
{
public Root root;
}
[StructLayout( LayoutKind.Sequential )]
public struct Root
{
public IntPtr instance;
}
}
提前致谢。
【问题讨论】:
标签: c# c pinvoke kotlin-native