我通过JNA从Java使用C库,并且一个函数没有正确刷新(因为输出在程序结束时一次显示)。我没试过Java边System.out.flush();
。
简而言之,我想从Java中调用C fflush(stdout)
。已经存在JNA(因此如果没有额外的库则更喜欢)并且没有C来编写。
我知道this question中的JNA库映射,但这对我来说似乎有点过分了。
答案 0 :(得分:2)
JNA库包装方式代码实际上并不那么重(至少对于flush all行为)。
protected interface CLibrary extends Library
{
static CLibrary clib = (CLibrary) Native.loadLibrary ("c", CLibrary.class);
int fflush (Pointer stream);
}
/* ... */
CLibrary.clib.fflush (null);
JNA还提供后期绑定方法,这些oneliner会做你想做的事情
NativeLibrary.getInstance ("c").getFunction ("fflush").invokeInt (new Object[]{0});
// even shorter
Function.getFunction ("c", "fflush").invokeInt (new Object[]{0});
当您想要将冲洗限制为stdout
时,会出现单调乏味的部分。您必须处理vendor-specific code(stdout被定义为扩展为数组的宏,Amtel avr-libc,函数调用,Microsoft msvcrt或GNU libc中的指针) 。
对于libc,您可以使用(两行易读性)
Pointer stdout = NativeLibrary.getInstance ("c").getGlobalVariableAddress ("stdout").getPointer (0);
Function.getFunction ("c", "fflush").invokeInt (new Object[]{stdout});
答案 1 :(得分:1)
为Win32 / Win64用户添加此答案,补充FabienAndre用于GNU libc。
选择性地刷新stdout流,通过jna调用系统的c库的fflush
方法是困难和繁琐的。正如FabienAndre已经提到的那样,很难掌握stdout
宏定义。对于msvcrt(Win32 / Win64 C库),它通过对__iob_func()
的函数调用来定义;后者返回一个指向FILE
结构数组的指针。索引0是stdin,索引1是stdout,索引2是stderr。因此,对于刷新标准版,你甚至需要知道FILE
结构的大小,当然,它对于Win32和Win64来说是不同的......
以下示例在Win64下测试但应该在Win32下运行。它的灵感来自线程JNA solutions to catch stdout/stderr of DLL。
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;
public class JnaTest {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary("msvcrt" , CLibrary.class);
Pointer __iob_func();
void printf(String format, Object... args);
int fflush (Pointer stream);
}
public static void main(String[] args) {
int sizeOfFileStructure = Platform.is64Bit() ? 48 : 32;
Pointer stdout = CLibrary.INSTANCE.__iob_func().share(sizeOfFileStructure);
CLibrary.INSTANCE.printf("Hello, World\n");
CLibrary.INSTANCE.fflush(stdout);
}
}