gpt4 book ai didi

C#调用返回结构的golang函数

转载 作者:行者123 更新时间:2023-12-01 22:23:08 27 4
gpt4 key购买 nike

我一直在尝试从 C# 对 go lib 中的函数进行互操作调用,该函数返回一个结构。
如果我理解正确,您必须在 go 中使用 CGO 才能返回更高级的数据类型。

我已经成功地调用了返回字符串的方法,返回结构的方法看起来更难解决。

在下面添加了一些示例代码。输出表明存在一些编码问题。

有什么建议么?
谢谢!

输出:

[go] Inspect
[go] main._Ctype_struct_foobar
[go] 0 : {A main._Ctype_long 0 [0] false} , 0
[go] 1 : {B *main._Ctype_char 8 [1] false} , 8
[C#] GetStruct
System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'return value': Invalid managed/unmanaged type combination (Int/UInt must be paired with SysInt or SysUInt).
at pinpoint.Program.GetStruct()
at pinpoint.Program.Main(String[] args) in /home/me/examples/pinpoint/Program.cs:line 14

构建/运行:
> env GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -o golib.so -buildmode=c-shared golib.go
> dotnet run

去代码:
package main

/*
#include <stdint.h>

struct foobar {
int64_t A;
char* B;
};

*/
import "C"

import (
"fmt"
"reflect"
)

//export Inspect
func Inspect() {
fmt.Println("[go] Inspect")
var foo = C.struct_foobar{}
t := reflect.TypeOf(foo)
fmt.Println("[go] ", t)
for i := 0; i < t.NumField(); i++ {
fmt.Println("[go] ", i, ":", t.Field(i), ",", t.Field(i).Offset)
}
}

//export GetStruct
func GetStruct(id string) *C.struct_foobar {
fmt.Println("[go] GetStruct")
var A int64 = 34
var B string = "AB"

var foo = C.struct_foobar{}
foo.A = C.int64_t(A)
foo.B = C.CString(B)

return &foo
}

func main() {}

C# 代码:
using System;
using System.Runtime.InteropServices;

namespace pinpoint
{
class Program
{
static void Main(string[] args)
{
try {
Inspect();
Console.WriteLine("[C#] GetStruct");
var ptr = GetStruct();
Console.WriteLine("[C#] Do marshal");
var foo = (Foo) Marshal.PtrToStructure(ptr, typeof(Foo));
Console.WriteLine($"[C#] foo = {foo}");
// FreeMem()
} catch (Exception e) {
Console.WriteLine(e);
}
}

// C type struct { int64_t A; char* B; }
[StructLayout(LayoutKind.Sequential)]
public struct Foo {
[MarshalAs(UnmanagedType.I8)]
public Int64 A;
[MarshalAs(UnmanagedType.LPTStr)]
public string B;
}

[DllImport("./golib.so", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern void Inspect();

[DllImport("./golib.so", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern IntPtr GetStruct();
}
}

最佳答案

最后,正在运行的东西。
(如果其他人可能觉得它有用,请回答自己)

当我删除 [return: MarshalAs(UnmanagedType.LPStruct)]。
它因以下输出而崩溃:“ panic :运行时错误:cgo 结果有 Go 指针”

这让我看到了这篇文章:https://groups.google.com/forum/#!topic/golang-nuts/uW9ehN4uXrM

一些重新安排:

C#

[DllImport("./golib.so", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern IntPtr GetStruct();


//export GetStruct
func GetStruct(id string) *C.struct_foobar {
fmt.Println("[go] GetStruct")
var A int64 = 34
var B string = "ABCD"

foo := (*C.struct_foobar) (C.malloc(C.size_t(unsafe.Sizeof(C.struct_foobar{}))))
foo.A = C.int64_t(A)
foo.B = C.CString(B)
return foo
}

关于C#调用返回结构的golang函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61716150/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com