Mono Embed サンプルに基づいて構築し、構造を更新する C# アセンブリ内のメソッドを呼び出してみました。構造体には 1 つの int 配列があります。これは Linux システム上にあります。
C# で int 配列フィールドにアクセスすると、セグメンテーション違反が発生します。フィールドが null かどうかを確認するだけで、エラーが発生します。
C# 内で内部マーシャリング シミュレーションを実行すると、構造体をバイトに変換してから構造体に戻すと、これは正常に機能します。
モノ バージョン: 3.2.3
以下に c# と c コードを含めました。必要に応じて、リクエストに応じて詳細情報を提供できます。
これがcコードです...
#include <mono/jit/jit.h>
#include <mono/metadata/object.h>
#include <mono/metadata/environment.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>
#include <string.h>
#include <stdlib.h>
#ifndef FALSE
#define FALSE 0
#endif
struct STRUCT_Test
{
int IntValue1[2];
};
int
main (int argc, char* argv[]) {
MonoDomain *domain;
MonoAssembly *assembly;
MonoClass *klass;
MonoObject *obj;
MonoImage *image;
const char *file;
int retval;
if (argc < 2){
fprintf (stderr, "Please provide an assembly to load\n");
return 1;
}
file = argv [1];
domain = mono_jit_init (file);
assembly = mono_domain_assembly_open(domain, file);
if (!assembly)
exit(2);
image = mono_assembly_get_image(assembly);
klass = mono_class_from_name(image, "StructTestLib", "StructReader");
if (!klass) {
fprintf(stderr, "Can't find StructTestLib in assembly %s\n", mono_image_get_filename(image));
exit(1);
}
obj = mono_object_new(domain, klass);
mono_runtime_object_init(obj);
{
struct STRUCT_Test structRecord; memset(&structRecord, 0, sizeof(struct STRUCT_Test));
void* args[2];
int val = 277001;
MonoMethodDesc* mdesc = mono_method_desc_new(":ReadData", FALSE);
MonoMethod *method = mono_method_desc_search_in_class(mdesc, klass);
args[0] = &val;
args[1] = &structRecord;
structRecord.IntValue1[0] = 1111;
structRecord.IntValue1[1] = 2222;
mono_runtime_invoke(method, obj, args, NULL);
printf("IntValue1: %d, %d\r\n", structRecord.IntValue1[0], structRecord.IntValue1[1]);
}
retval = mono_environment_exitcode_get ();
mono_jit_cleanup (domain);
return retval;
}
これがC#コードです...
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace StructTestLib
{
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct STRUCT_Test
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public Int32[] IntValue1;
}
public class StructReader
{
public void ReadData(int uniqueId, ref STRUCT_Test tripRecord)
{
if (tripRecord.IntValue1 != null)
Console.WriteLine("IntValue1: " + tripRecord.IntValue1[0] + ", " + tripRecord.IntValue1[1]);
else
Console.WriteLine("IntValue1 is NULL");
tripRecord.IntValue1[0] = 3333;
tripRecord.IntValue1[1] = 4444;
}
}
}