Fairly new to JNA but getting Invalid memory access for trying to link a Fortran dll.
The fortran code:
FUNCTION OpenFile(FileName,LenFileName) RESULT(Stat)
INTEGER,INTENT(IN) :: LenFileName
CHARACTER(LEN=LenFileName),INTENT(IN) :: FileName
INTEGER :: Stat
!Set the level of messaging to error and warning messages only
CALL ZSET('MLEVEL','',0)
!Set an unconnected unit number for the file
CALL ZSET('UNIT','',1111)
!Open file
CALL ZOPEN(IFLTAB(:,iOpenFiles+1),FileName,Stat)
iOpenFiles = iOpenFiles + 1
cFileNames(iOpenFiles) = FileName
END FUNCTION OpenFile
The interface:
public interface test extends com.sun.jna.Library {
test reader = (test) Native.loadLibrary("test.dll", test.class);
int OpenFile(String FileName, int LenFileName);
}
And calling it using this:
int ret = test.reader.OpenFile(fileName, fileName.length());
Error Im recieving
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.OpenFile(Unknown Source)
Java Result: 1
Try using JNAerator util to provide apriori correct method mappings.
Related
Googlemock can help build mock classes with which it is possible to detect if one method calls another method and with what parameters, and influence the behaviour of the called method.
E.g., to test that method a() in class UnderTest actually calls method b()
class UnderTest {
public:
/// Method a() calls method b().
virtual void a() {b();}
/// Method b() does nothing.
virtual void b() {}
};
one can write a mock class which overwrites method b()
class UnderTestMock : public UnderTest {
public:
MOCK_METHOD0(b, void());
};
and test if the method b() is actually called after calling method a():
TEST(UnderTest, aCallsB) {
UnderTestMock mock;
EXPECT_CALL(mock, b());
mock.a();
}
Can I use Googlemock like this with C++Builder 11.2?
No, at the moment it is not possible to use Googlemock like this with C++Builder 11.2.
The Googletest project (which includes Googlemock) itself has removed all support for C++Builder in 2019. Embarcadero has since published their own patched version of Googletest in a GetIt package, which includes project files to build Googletest and Googlemock and some usage examples.
The Googlemock-related project files are all somewhat broken, e.g. the gmock.cbproj file inserts a source file into the gmock.a library that performs some unrelated tests on Googletest. These project file errors can all be fixed easily by removing source files from the projects that do not belong there and rebuild.
However, after fixing the gmock.cbproj project file, it turns out that the main feature of Googlemock, the EXPECT_CALL() macro, is not supported by C++Builder 11.2:
This is a simple source file which puts the code pieces from the question together, adds a main function and the required includes:
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
class UnderTest {
public:
/// Method a() calls method b().
virtual void a() {b();}
/// Method b() does nothing.
virtual void b() {}
};
class UnderTestMock : public UnderTest {
public:
MOCK_METHOD0(b, void());
};
TEST(UnderTest, aCallsB) {
UnderTestMock mock;
EXPECT_CALL(mock, b());
mock.a();
}
This sample works fine with Googlemock with other compilers (at most, tchar, _tmain need to be replaced with char, main), however, with C++Builder, some required features are missing from either the compiler or from the C++ standard library. The error message when compiling with C++Builder's clang-based 64-bit compiler is
Build FAILED.
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-nice-strict.h(134,6): C++ warning : __declspec attribute 'empty_bases' is not supported
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-nice-strict.h(174,6): C++ warning : __declspec attribute 'empty_bases' is not supported
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-nice-strict.h(215,6): C++ warning : __declspec attribute 'empty_bases' is not supported
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\type_traits(2686,1): C++ error : no matching function for call to 'invoke'
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\functional(216,10): C++ error : > in instantiation of function template specialization 'std::_Invoke_ret<void, testing::internal::DoDefaultAction &>' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\functional(165,2): C++ error : > in instantiation of member function 'std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void>::_Do_call' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\xmemory0(704,23): C++ error : > in instantiation of function template specialization 'std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void>::_Func_impl<testing::internal::DoDefaultAction, const std::allocator<int> &>' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\xmemory0(845,6): C++ error : > in instantiation of function template specialization 'std::allocator<std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void> >::construct<std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void>, testing::internal::DoDefaultAction, const std::allocator<int> &>' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\xmemory0(994,13): C++ error : > in instantiation of function template specialization 'std::allocator_traits<std::allocator<std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void> > >::construct<std::_Func_impl<testing::internal::DoDefaultAction, std::allocator<int>, void>, testing::internal::DoDefaultAction, const std::allocator<int> &>' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\functional(376,6): C++ error : > (skipping 6 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-actions.h(470,4): C++ error : > in instantiation of function template specialization 'testing::Action<void ()>::Init<testing::internal::DoDefaultAction>' requested here
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-spec-builders.h(909,8): C++ error : > in instantiation of function template specialization 'testing::Action<void ()>::Action<testing::internal::DoDefaultAction, void>' requested here
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-spec-builders.h(1629,12): C++ error : > in instantiation of member function 'testing::internal::TypedExpectation<void ()>::TypedExpectation' requested here
C:\Users\...\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googlemock\include\gmock/gmock-spec-builders.h(1284,29): C++ error : > in instantiation of member function 'testing::internal::FunctionMocker<void ()>::AddNewExpectation' requested here
C:\Users\...\Documents\Embarcadero\Studio\Projects\gmocktest\main.cpp(26,2): C++ error : > in instantiation of member function 'testing::internal::MockSpec<void ()>::InternalExpectedAt' requested here
c:\program files (x86)\embarcadero\studio\22.0\include\dinkumware64\type_traits(2664,6): C++ error : > candidate template ignored: substitution failure [with _Callable = testing::internal::DoDefaultAction &, _Types = <>]: no matching function for call to '_Call'
3 Warning(s)
13 Error(s)
The two example projects included in the GetIt package for Googlemock hint that some isolated aspects of Googlemock may be working, like at least one Googlemock matcher works inside the EXPECT_THAT() macro, but none of the examples compiled by the GetIt package make use of the main feature of Googlemock, the EXPECT_CALL() macro.
The following dart code's expected output is the handle to the file explorer window but the output always comes out to be 0 even though the file explorer window does exist!
import 'package:ffi/ffi.dart';
import 'dart:ffi';
void main() {
DynamicLibrary dl = DynamicLibrary.open('user32.dll');
final func = dl.lookupFunction<
IntPtr Function(Pointer<Utf16>?, Pointer<Utf16>?),
int Function(Pointer<Utf16>?, Pointer<Utf16>?)
>('FindWindowA');
print(func(nullptr, 'File Explorer'.toNativeUtf16()));
}
I have ran the function FindWindowA in a c++ program and it has returned the exptected output with the same input values that are NULL and 'File Explorer'.
In dart using null throws the error Invalid argument(s): argument value for ':ffi_param1' is null; hence the use of nullptr
FindWindowA does not take pointers to UTF-16 strings. The A in FindWindowA stands for "ANSI", which is Microsoft's way of indicating that it uses strings with single-byte code units encoded in the system's local encoding. (This is also indicated by its signature, which takes LPCSTR arguments.)
If you want to pass UTF-16 strings (which in Microsoft Windows are considered "wide strings"), then use FindWindowW.
When running the following command: sourceanalyzer -debug -b $build_id touchless make
I'm getting this error:
Compiling C++ myFile.C
[ERROR]: Translator execution failed. Please consult the Troubleshooting section of the User Manual.
Translator returned status 139:
“/usr/include/c++/4.3/atomicity.h”, line 51: warning identifier
“__sync_fetch_and_add” is undefined
{ return __sync_fetch_and_add(__mem, __val); }
“/usr/include/c++/4.3/atomicity.h”, line 55: warning identifier
“__sync_fetch_and_add” is undefined
{ __sync_fetch_and_add(__mem, __val); }
“/usr/include/c++/4.3/new”, line 95: warning: first parameter of allocation
Function must be of type “size_t”
Void* operator new(std::size_t) throw (std::bad_alloc);
“/usr/include/c++/4.3/new”, line 96: warning: first parameter of allocation
Function must be of type “size_t”
Void* operator new[](std::size_t) throw (std::bad_alloc);
“/usr/include/c++/4.3/new”, line 99: warning: first parameter of allocation
Function must be of type “size_t”
Void* operator new(std::size_t, const std::nothrow_t&) throw ();
“/usr/include/c++/4.3/new”, line 100: warning: first parameter of allocation
Function must be of type “size_t”
Void* operator new[](std::size_t, const std::nothrow_t&) throw ();
“/usr/include/c++/4.3/new”, line 105: warning: first parameter of allocation
Function must be of type “size_t”
Inline void* operator new(std::size_t, void* __p) throw (){ return __p; }
“/usr/include/c++/4.3/new”, line 105: warning: first parameter of allocation
Function must be of type “size_t”
Inline void* operator new[](std::size_t, void* __p) throw (){ return __p; }
“/opt/ilog51/views51/include/ilog/list.h”, line 77: warning: first parameter of allocation function must be of type “size_t”
IL_MLK_DECL();
“/opt/ilog51/views51/include/ilog/list.h”, line 110: warning: no appropriate operator delete is visible
{ e(); delete_first; _first; _first = _last 0; _length = 0; }
Furthermore, when uploading the FPR file to SSC, under Artifacts the status is: Error Processing. And when auditing issues, the ssc is unable to locate source files.
Any ideas about this issues ?
One idea is that the older gcc 4.3 (year 2008?) used compiler built-ins that were specific to GCC, while Fortify relies on Clang to translate the source code.
https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html
I use a C library from Java through JNA and one function does not flush properly (since the output appear all at once on program end). I have tried Java side System.out.flush(); with no luck.
In brief, I would like to call C fflush(stdout) from Java. With JNA already there (thus would prefer if no additional library) and without C to write.
I am aware of JNA Library mapping as in this question but that seems overkill to me.
The JNA library wrapping way code is actually not so heavy (at least for the flush all behavior).
protected interface CLibrary extends Library
{
static CLibrary clib = (CLibrary) Native.loadLibrary ("c", CLibrary.class);
int fflush (Pointer stream);
}
/* ... */
CLibrary.clib.fflush (null);
JNA also offer late binding method and these oneliners will do what you want
NativeLibrary.getInstance ("c").getFunction ("fflush").invokeInt (new Object[]{0});
// even shorter
Function.getFunction ("c", "fflush").invokeInt (new Object[]{0});
The tedious part comes when you want to limit flushing to stdout. You have to deal with vendor-specific code (stdout is either defined as a macro expanding to an array, Amtel avr-libc, to a function call, Microsoft msvcrt, or a pointer in GNU libc).
For the libc, you might use (two lines for legibility)
Pointer stdout = NativeLibrary.getInstance ("c").getGlobalVariableAddress ("stdout").getPointer (0);
Function.getFunction ("c", "fflush").invokeInt (new Object[]{stdout});
Adding this answer for Win32 / Win64 users, complementing FabienAndre's for GNU libc.
Selectively flushing the stdout stream calling the system's c library's fflush method via jna is hard and cumbersome. As FabienAndre already mentioned, it is difficult to get a hold of the stdout macro definition. For msvcrt (the Win32 / Win64 C library) it is defined via a function call to __iob_func(); the latter returning a pointer to an array of FILE structures. At index 0 is stdin, index 1 is stdout and index 2 is stderr. So for flushing stdout you even need to know the size of the FILE structure, of course, it is different for Win32 and Win64 ...
The following example is tested under Win64 but ought to work under Win32. It was inspired by the thread 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);
}
}
I am trying to call a simple Lua function from Java using LuaJava.
calc.lua:
function foo(n) return n*2 end
Thats all there is in calc.lua and subsequent calls from command line work.
Here is the call that always has error :
L.getGlobal("foo");
L.pushNumber(8.0);
int retCode=L.pcall(1, 1,-2); // retCode value is always 5 pcall(numArgs,numRet,errHandler)
String s = L.toString(-1); // s= "Error in Error Handling Code"
I have also tried
L.remove(-2);
L.insert(-2);
Not sure why its giving any error at all or what the error is. Maybe I'm not setting up error handler correctly? So it does not make the call? After load I tried from console and can run print(foo(5)) getting back 10 as expected.
UPDATE: It looks like I need to provide an error handler on the stack. What is the signature for such an error handler and how would I place it at a point on the stack. Thanks
This is taken from the Lua reference manual -- under the C API section it says this about pcall:
When you call a function with lua_call, any error inside the called function is propagated upwards (with a longjmp). If you need to handle errors, then you should use lua_pcall:
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
...
If errfunc is 0, then the error message returned is exactly the
original error message. Otherwise, errfunc gives the stack index for
an error handler function. (In the current implementation, that index
cannot be a pseudo-index.) In case of runtime errors, that function
will be called with the error message and its return value will be the
message returned by lua_pcall
So assuming LuaJava's API just mirrors the C API, then just pass 0 to indicate no special errfunc. Something like this should work:
int retCode = L.pcall(1, 1, 0);
String errstr = retCode ? L.toString(-1) : "";
Why on earth have you provided -2? That should not be there. You have told Lua that on the Lua stack there exists an error function that will deal with the error at the index -2, while your code does not indicate anything of the sort. pcall should only take two arguments in most cases.