将参数从C传递给Embedded Mono [英] Passing arguments from C to Embedded Mono

查看:91
本文介绍了将参数从C传递给Embedded Mono的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用嵌入式mono从C调用简单的C#类方法(如

I am trying to invoke a simple C# class method from C, using embedded mono (as described here). I can invoke the method, but the C# function receives 0 as the argument, instead of the number I pass in. The C# function returns a result and the C code is seeing the correct result - I just can't pass arguments in. What am I doing wrong?

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

The C# assembly (MonoSide.cs) is:

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进行编译:

I am compiling it with Dev-Cpp using this makefile:

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

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

(Why these functions? This is just a sample, can-I-get-this-to-work program and not my final goal.)

如果我将函数参数作为指针传递给C代码,则它可以工作. C#正确接收到它.上面的代码已被修改自:

It works if I pass the function argument as a pointer in the C code. The C# receives it correctly. The above code has been modified from:

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#中使用匹配的序列化器和反序列化器.

To me, this means that the safest way to pass anything more complicated between C and C# is via buffers, with matching serializers and deserializers in C and C#.

推荐答案

如果我将函数参数作为C语言中的指针传递,它将起作用. C#正确接收到它.上面的代码已被修改自:

It works if I pass the function argument as a pointer in the C code. The C# receives it correctly. The above code has been modified from:

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#中使用匹配的序列化器和反序列化器.

To me, this means that the safest way to pass anything more complicated between C and C# is via buffers, with matching serializers and deserializers in C and C#.

这篇关于将参数从C传递给Embedded Mono的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆