Странное поведение Java FFM на платформе Windows при создании UPCALLS, принимая как структуру, так и параметры указателяJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Странное поведение Java FFM на платформе Windows при создании UPCALLS, принимая как структуру, так и параметры указателя

Сообщение Anonymous »

На платформе Windows при создании APC -заглушек с помощью API Java 22 FFM, если функции обратного вызова имеют как структура (больше, чем размер указателя) и PAMERETERS, то память S будет принимать эти параметры указателя с конфигурированным сеансом памяти. Такое поведение не согласуется с Linux jvm. < /P>
mwe здесь: < /p>
:

Код: Выделить всё

#include 
#include 

typedef struct {
char const *s1;
char const *s2;
} S;

typedef void (*callback_fn)(S s, char const *data);

#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __attribute__((visibility("default")))
#endif

EXPORT extern void ccb(callback_fn fn) {
char const *data = "Let's be together, forever, we are never gonna be apart.";

fprintf(stderr, "(C) address of data = %p\n", (void*)data);

fn(
((S) {
"Shall I leave you be, Is it love if I can set you free?",
"But even it's not reality,",
}),
data
);
}
Здесь данные , предоставленные для fn - статическая строка из мира C. Конечно, он не выделен из мира Java.

Код: Выделить всё

gcc.exe ccb.c -shared -fPIC -o ccb.dll
< /code>
или < /p>
cl.exe /utf-8 /nologo /LD /MD /DWIN32 /Zi ccb.c /Fe:ccb.dll /link User32.lib
< /code>

CCB.java
:
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;

public final class CCB {
static final StructLayout LAYOUT$S = MemoryLayout.structLayout(
ValueLayout.ADDRESS.withTargetLayout(ValueLayout.JAVA_BYTE).withName("s1"),
ValueLayout.ADDRESS.withTargetLayout(ValueLayout.JAVA_BYTE).withName("s2")
);

static final FunctionDescriptor DESCRIPTOR$ccb = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS.withName("fn"));

static final FunctionDescriptor DESCRIPTOR$callback = FunctionDescriptor.ofVoid(
LAYOUT$S.withName("s"),
ValueLayout.ADDRESS.withTargetLayout(ValueLayout.JAVA_BYTE).withName("data")
);

static final MethodHandle hCCB;
static {
System.loadLibrary("ccb");

Linker linker = Linker.nativeLinker();
SymbolLookup stdlibLookup = linker.defaultLookup();
SymbolLookup loaderLookup = SymbolLookup.loaderLookup();

MemorySegment pfnCCB = loaderLookup.find("ccb")
.or(() -> stdlibLookup.find("ccb"))
.orElse(MemorySegment.NULL);
if (pfnCCB.equals(MemorySegment.NULL)) {
throw new RuntimeException("Failed to find ccb symbol");
}
hCCB = linker.downcallHandle(pfnCCB, DESCRIPTOR$ccb);
}

static final class Ref {
T value;
}

@FunctionalInterface
interface MemorySegmentConsumer {
void accept(MemorySegment segment);
}

static void callback(
MemorySegmentConsumer consumer,
MemorySegment s,
MemorySegment data
) {
for (int i = 0; i < 2; i++) {
MemorySegment segment = s.getAtIndex(ValueLayout.ADDRESS, i).reinterpret(Long.MAX_VALUE);
System.err.println("(J) callback: s->s" + (i + 1) + " = " + segment.getString(0));
}
data = data.reinterpret(Long.MAX_VALUE);
System.err.println("(J) callback: data = " + data.getString(0));
System.err.println("(J) callback: address of data = " + Long.toUnsignedString(data.address(), 16));

consumer.accept(data);
}

public static void main(String[] args) {
Ref ref = new Ref();
MemorySegmentConsumer consumer = segment -> ref.value = segment;

try (Arena arena = Arena.ofConfined()) {
Linker linker = Linker.nativeLinker();
MethodHandle MH$callback = MethodHandles.lookup().findStatic(
CCB.class,
"callback",
DESCRIPTOR$callback.toMethodType().insertParameterTypes(0, MemorySegmentConsumer.class)
);
MemorySegment pfnCallback = linker.upcallStub(
MH$callback.bindTo(consumer),
DESCRIPTOR$callback,
arena
);

hCCB.invokeExact(pfnCallback);

System.err.println("(J) main: data = " + ref.value.getString(0)); //

Program output:
(J) callback: s->s1 = Shall I leave you be, Is it love if I can set you free?
(J) callback: s->s2 = But even it's not reality,
(J) callback: data = Let's be together, forever, we are never gonna be apart.
(J) callback: address of data = 7fffa5009000
Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalStateException: Already closed
at CCB.main(CCB.java:81)
Caused by: java.lang.IllegalStateException: Already closed
at java.base/jdk.internal.foreign.MemorySessionImpl.alreadyClosed(MemorySessionImpl.java:318)
at java.base/jdk.internal.misc.ScopedMemoryAccess$ScopedAccessError.newRuntimeException(ScopedMemoryAccess.java:114)
at java.base/jdk.internal.misc.ScopedMemoryAccess.getLongUnaligned(ScopedMemoryAccess.java:2574)
at java.base/jdk.internal.foreign.StringSupport.strlenByte(StringSupport.java:142)
at java.base/jdk.internal.foreign.StringSupport.readByte(StringSupport.java:71)
at java.base/jdk.internal.foreign.StringSupport.read(StringSupport.java:54)
at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.getString(AbstractMemorySegmentImpl.java:907)
at java.base/jdk.internal.foreign.AbstractMemorySegmentImpl.getString(AbstractMemorySegmentImpl.java:900)
at CCB.main(CCB.java:79)
(C) address of data = 00007fffa5009000
< /code>

And when observed from IDE:
Изображение


Such behavior is not observed when there's only pointer parameters, and not observed when the structure is smaller (only 1 pointer size).
Also, this behavior is not observed on Linux:
Изображение

Is this some kind of deliberate design, technical limitation or bug?

Подробнее здесь: https://stackoverflow.com/questions/797 ... -accepting
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Приводит ли адрес указателя на структуру к адресу структуры, первый член которой является указателем на структуру UB?
    Anonymous » » в форуме C++
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous
  • Принимая параметры поближений путем ссылки на RVALU
    Anonymous » » в форуме C++
    0 Ответы
    3 Просмотры
    Последнее сообщение Anonymous
  • Принимая параметры поближений путем ссылки на RVALU
    Anonymous » » в форуме C++
    0 Ответы
    3 Просмотры
    Последнее сообщение Anonymous
  • Управление панелью задач в Windows из Java с помощью FFM и winapi
    Anonymous » » в форуме JAVA
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Управление панелью задач в Windows из Java с помощью FFM и winapi
    Anonymous » » в форуме JAVA
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»