如何在Java和C#之间为JNA包装它时,在非托管C中创建托管对象?

前端之家收集整理的这篇文章主要介绍了如何在Java和C#之间为JNA包装它时,在非托管C中创建托管对象?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我试图使用JNA在C#和Java之间建立一个回调接口.

C#< - CLI - > Visual C 2010< - JNA - > Java的

在Java和C之间我使用非托管结构来获得回调功能.在C中我试图将具有回调指针的结构包装到托管对象中.

在Java和C之间,一切正常,直到我尝试使用gcroot在非托管代码生成托管对象.

更新它甚至没有gcroot失败.只需使用“Logger ^ logger = gcnew Logger(logStruct);”

我目前的解决方案如下:

Java的

LoggerStruct.java

package jnatest;

import com.sun.jna.Callback;
import com.sun.jna.Structure;
import java.util.logging.Logger;

public class LoggerStruct extends Structure {
    private Logger logger;

    public interface GetLevelCallback extends Callback {
        int callback();
    }

    public GetLevelCallback getLevel;

    public LoggerStruct(Logger log) {
        super();
        this.log = log;

        getLevel = new GetLevelCallback() {
            public int callback() {
                return logger.getLevel().intValue();
            }
        }

        setFieldOrder(new String[] {"getLevel"});
    }
}

ITestLib.java

package jnatest;

import com.sun.jna.Library;
import com.sun.jna.Native;

public interface ITestLib extends Library {
    ITestLib INSTANCE = (ITestLib) Native.loadLibrary("JNATestC",ITestLib.class);
    int callbackTest(LoggerStruct logStruct);
}

Main.java

package jnatest;

import com.sun.jna.NativeLibrary;
import java.util.logging.Logger;
import java.util.logging.FileHandler;

public class MainClass {
    public static void main(String[] args) throws Exception  {
        NativeLibrary.addSearchPath("JNATestC","C:\\JNATest");

        Logger log = Logger.getLogger("Test");
        FileHandler fileTxt = new FileHandler("Logging.txt");
        log.addHandler(fileTxt);

        LoggerStruct logStruct = new LoggerStruct(log);

        ITestLib.INSTANCE.callbackTest(logStruct);
    }
}

C

JNATestC.h

#pragma once

extern "C" {
    struct LoggerStruct {
        int (*getLevel)();
    }
    __declspec(dllexport) void callbackTest(LoggerStruct * logStruct);
}

namespace JnaWrapperTypes {
    public ref class Logger { // "public ref" because I have to use it in C# as well
        private:
            LoggerStruct * logStruct;
        public:
            Logger(LoggerStruct * logStruct);
            ~Logger() {} 
            int getLevel();
    };
}

JNATestC.cpp

#include "stdafx.h"
#include 

我在飞行中写了这些.我希望这些也可以验证.

我究竟做错了什么?例如,如果我使用…

gcroot

……一切正常

是否有另一种方法将托管对象传递给C#?

记录此错误LOG

UPDATE

似乎任何我自己的Class用法都会让我失败.

UPDATE

我自己管理的对象或函数的Anykind使我失败.

UPDATE

StaticCSharpClass :: STATICMETHOD();也失败了.看起来所有与托管对象相关的操作都会失败.

UPDATE

如果我从.NET调用相同的方法,一切正常.

只是为了让这个问题更容易找到
内部错误(0xe0434352)

最佳答案
应该用Google搜索错误“内部错误(0xe0434352)”.

http://jira.talendforge.org/browse/TDI-19427

这导致我必须为GAC(全局程序集缓存)注册dll,因为Java只搜索GAC和Application Base目录中的dll.并且因为Java.exe路径不可配置.

==解决方案==

使用post build事件为GAC注册程序集:

gacutil /i "$(TargetPath)"

伟大的独白! =)

猜你在找的Java相关文章