将参数从 C 传递到 Embedded Mono

Posted

技术标签:

【中文标题】将参数从 C 传递到 Embedded Mono【英文标题】:Passing arguments from C to Embedded Mono 【发布时间】:2015-03-26 23:18:30 【问题描述】:

我正在尝试使用嵌入式单声道从 C 调用一个简单的 C# 类方法(如 here 所述)。我可以调用该方法,但 C# 函数接收 0 作为参数,而不是我传入的数字。C# 函数返回一个结果,C 代码看到正确的结果 - 我只是无法传入参数。什么我做错了吗?

C# 程序集 (MonoSide.cs) 是:

using System;

public class MainEntryPoint

   static public void Main(string[] args)
   
   


namespace Fibonacci

    public class Fibonacci
    
        public long FibonacciNumber(long entryNumber)
        
            Console.Write(string.Format("(inside C#) FibonacciNumber(0)", entryNumber));
            var sqrt5 = Math.Sqrt(5);
            var phi = (1 + sqrt5) / 2;
            var exp = Math.Pow(phi, entryNumber);
            var sign = ((entryNumber & 1) == 0) ? -1 : 1;
            var entry = (exp + sign / exp) / sqrt5;

            Console.WriteLine(string.Format(" = 0.", entry));
            return (long) entry;
        
    

这是 C 代码:

#include <stdio.h>
#include <stdlib.h>
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>

int main(int argc, char **argv)

    long long entryNumber = (argc > 1) ? atoi(argv[1]) : 10;

    // For brevity, null checks after each mono call are omitted.
    MonoDomain *domain = mono_jit_init("MainEntryPoint");
    MonoAssembly *monoAssembly = mono_domain_assembly_open(domain, "MonoSide.exe");
    char *monoArgs[] = "Mono";
    mono_jit_exec (domain, monoAssembly, 1, monoArgs);

    MonoImage * monoImage = mono_assembly_get_image (monoAssembly);
    MonoClass * monoClass = mono_class_from_name (monoImage, "Fibonacci", "Fibonacci");

    MonoMethod *monoMethod = mono_class_get_method_from_name(monoClass, "FibonacciNumber", 1);

    // Invoking method via thunk.
    typedef long long (*FibonacciNumber) (long long *);
    FibonacciNumber fibonacciNumber = mono_method_get_unmanaged_thunk (monoMethod);

    printf("Calling C# thunk function FibonacciNumber(%I64u)...\n", entryNumber);
    long long number = fibonacciNumber(&entryNumber);

    printf("Fibonacci number %I64u = %I64u\n", entryNumber, number);

    mono_jit_cleanup (domain);

    return 0;

我正在使用这个 makefile 用 Dev-Cpp 编译它:

test.exe: CSide.c MonoSide.exe
    gcc CSide.c -o test.exe -m32 -mms-bitfields -IC:/Progra~2/Mono/Include/mono-2.0 -LC:/Progra~2/Mono/lib -L/Embedded -lmono-2.0 -lmono

MonoSide.exe: MonoSide.cs
    mcs MonoSide.cs

输出是:

Calling C# thunk function FibonacciNumber(10)...
(inside C#) FibonacciNumber(0) = 0.
Fibonacci number 10 = 0

(为什么要使用这些功能?这只是一个示例,我可以得到这个工作程序,而不是我的最终目标。)

编辑:

如果我将函数参数作为 C 代码中的指针传递,它就可以工作。 C# 正确接收它。上述代码修改自:

typedef long long (*FibonacciNumber) (long long);
...
long long number = fibonacciNumber(entryNumber);

到:

typedef long long (*FibonacciNumber) (long long *);
...
long long number = fibonacciNumber(&entryNumber);

对我来说,这意味着在 C 和 C# 之间传递更复杂的东西的最安全方法是通过缓冲区,在 C 和 C# 中使用匹配的序列化器和反序列化器。

【问题讨论】:

【参考方案1】:

如果我将函数参数作为 C 代码中的指针传递,它就可以工作。 C# 正确接收它。上述代码修改自:

typedef long long (*FibonacciNumber) (long long);
...
long long number = fibonacciNumber(entryNumber);

到:

typedef long long (*FibonacciNumber) (long long *);
...
long long number = fibonacciNumber(&entryNumber);

对我来说,这意味着在 C 和 C# 之间传递更复杂的东西的最安全方法是通过缓冲区,在 C 和 C# 中使用匹配的序列化器和反序列化器。

【讨论】:

以上是关于将参数从 C 传递到 Embedded Mono的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C++/CLI Wrapper 将变量参数从托管传递到非托管?

如何将函数作为参数从 C 传递到 C++ 并返回到 C

C:将可变数量的参数从一个函数传递到另一个函数

如何将参数从c ++传递到linux shell

C# MVC 使用 dotnetfiddle 将参数从视图传递到控制器

将参数从cmd传递到python脚本[重复]