【问题标题】:JNA: java.lang.Error: Invalid memory access - TS3 LibraryJNA:java.lang.Error:无效的内存访问 - TS3 库
【发布时间】:2015-06-05 23:59:12
【问题描述】:

我正在使用 JNA 从 Java 访问一些 dll 函数,这个 dll Native Function 声明如下:

unsigned int ts3client_initClientLib(const struct ClientUIFunctions* functionPointers, const struct ClientUIFunctionsRare* functionRarePointers, int usedLogTypes, const char* logFileFolder, const char* resourcesFolder);

因此,我在库接口中声明如下:

int ts3client_initClientLib(Structure functionPointers, Structure functionRarePointers, int usedLogTypes, String logFileFolder, String resourcesFolder);

然后我这样称呼它:

ts3client_initClientLib(null, null, 1, "log.log", "soundbackends");

但我收到以下异常:

Exception in thread "main" java.lang.Error: Invalid memory access
    at com.sun.jna.Native.invokeInt(Native Method)
    at com.sun.jna.Function.invoke(Function.java:383)
    at com.sun.jna.Function.invoke(Function.java:315)
    at com.sun.jna.Library$Handler.invoke(Library.java:212)
    at com.sun.proxy.$Proxy0.ts3client_initClientLib(Unknown Source)
    at pl.edu.tirex.ts3musicbot.MusicBot.main(MusicBot.java:17)

【问题讨论】:

  • 目标函数很可能需要一个非 NULL 结构,其中填充了回调,您在其中给它一个 NULL 指针。

标签: java jna


【解决方案1】:

正确的解决方案:

创建事件接口:

import com.sun.jna;

public interface ServerErrorEvent implements Callback
{
    void invoke(long serverConnectionHandlerID, String errorMessage, int error, String returnCode, String extraMessage);
}

创建客户端 UI 功能结构:

import com.sun.jna.Structure;

public class EventsStructure extends Structure
{
    public ServerErrorEvent onServerErrorEvent;

    @SuppressWarnings("rawtypes")
    @Override
    protected List<String> getFieldOrder() 
    {
        List<String> fields = new ArrayList<String>();
        for (Field f : this.getClass().getDeclaredFields())
        {
            boolean has = false;
            for (Class<?> c : f.getType().getInterfaces())
            {
                if (c.equals(DefaultEvent.class))
                {
                    has = true;
                }
            }
            if (has)
            {
                fields.add(f.getName());
            }
        }
        return fields;
    }
}

使用以下方法:

EventsStructure eventStructure = new EventsStructure();
eventStructure.onServerErrorEvent = new ServerErrorEvent() //implement server error event
{
    @Override
    public void invoke(long serverConnectionHandlerID, String errorMessage, int error, String returnCode, String extraMessage)
    {
        System.out.println("server error");
    }
};
ts3client_initClientLib(eventStructure, null, 0, "logs", "soundbackends"); //invoke ts3client_initClientLib function from library

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多