JNI Error : java.lang.NoSuchMethodError: no static method - c++

Error Message : Pending exception java.lang.NoSuchMethodError thrown by 'void com.exampleTest.NDKT.I(android.app.Activity):-2'
java.lang.NoSuchMethodError: no static method "Lcom/exampleTest/NDKT;.PN()Ljava/lang/String;"
I should try ndk c++ call java method because i want you java method thought android package name know
i tried below
java call method String -> void change
=> c++ : jmethodID jMethod = pE->GetStaticMethodID(jClass, "GO", "()V");
java code "this" -> "MainActivity.this"
- Java code
CallNDK class{
public static void initialize(final Activity a,final SIMECB cb) {
System.loadLibrary("simpleinit");
_CB = cb;
_INSTANCE = new CallNDK();
new Thread(new Runnable() {
public void run() {
_INSTANCE.I(a);
}
}).start();
}
}
==> initialize () -> Activity = MainActivity.this
- NDK
CallNDK.cpp
static string mPN; //Packege Name
#ifdef __ANDROID__
void CallNDK::I(JNIEnv* pE, jobject pA){
// Package Name Method call
CHECK::PN(pE, mPN);
}
CHECK.h
#ifndef CHECK_H_
#define CHECK_H_
#ifdef __ANDROID__
#include <jni.h>
#endif
using namespace std;
class CHECK {
public:
#ifdef __ANDROID__
static void PN(
JNIEnv* pE,
string& pO);
#endif
};
#endif
CHECK.cpp
#include "CHECK.h"
#ifdef __ANDROID__
#include <jni.h>
#endif
using namespace std;
#ifdef __ANDROID__
void CHECK::PN(JNIEnv* pE, string& pO){
jclass classes = pE->FindClass("com/exampleTest/NDKT");
jmethodID jMethod = pE->GetMethodID(classes, "SimpleMethod", ()Ljava/lang/String;");
if(!jMethod) {
CALLUtil::LOG("class loader method access");
return;
}
jstring jsResult = (jstring)pE->CallStaticObjectMethod(jClass, jMethod);
const char* cResult = pE->GetStringUTFChars(jsResult, NULL);
std::string sResult(cResult);
pO = sResult;
}
- NDK of call java class code
enter code here
NDKT Class {
private static int _MAX_TRY_INVOKE_COUNT = 5;
public static String SimpleMethod(Activity a){
for(int i = 0; i < _MAX_TRY_INVOKE_COUNT; i++) {
try {
return a.getApplicationContext().getPackageName();
} catch (Exception e) {
try { Thread.sleep(50); } catch (Exception e2) { }
}
}
return ""
}
}
Error
JNI DETECTED ERROR IN APPLICATION:
JNI FindClass called with pending exception 'java.lang.NoSuchMethodError' thrown in void com.exampleTest.CallNDK.I(android.app.Activity):-2 in call to FindClass from void com.exampleText.CallNDK.I(android.app.Activity)
Pending exception java.lang.NoSuchMethodError thrown by 'void com.exampleTest.NDKT.I(android.app.Activity):-2'
java.lang.NoSuchMethodError: no static method "Lcom/exampleTest/NDKT;.PN()Ljava/lang/String;"

Related

Export to HTML5 FWebSocketsModule not working

I'm exporting UE4 Project (version 4.23) to HTML5 that has WebSockets module enabled in .Build.cs:
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "WebSockets" });
It works fine when I play in Editor, but when I call FWebSocketsModule::Get().CreateWebSocket(url, protocol) on exported project, this method is not found.
Did check FWebSocketsModule.cpp and function is declared:
#if WITH_WEBSOCKETS
TSharedRef<IWebSocket> FWebSocketsModule::CreateWebSocket(....
....
#endif
So, WITH_WEBSOCKETS is set to 0 when exporting/running to html
I did declare this macro on my class and set to 1, but it got stuck at Loading engine... in browser
Did I miss any configuration?
Managed to call websockets from HTML by including emscripten websockets
in <Project>.Build.cs constructor:
if (Target.Platform == UnrealTargetPlatform.HTML5)
{
string libwebs = "<Engine instal dir>/UE_4.23/Engine/Extras/ThirdPartyNotUE/emsdk/emscripten/1.38.31/src/library_websocket.js";
PublicAdditionalLibraries.Add(libwebs);
}
In my GameInstance.h class (or whenever you want to register websockets):
#ifdef __EMSCRIPTEN__
#include <emscripten/html5.h>
#include <emscripten/emscripten.h>
#include <emscripten/websocket.h>
#endif
In .cpp class:
#ifdef __EMSCRIPTEN__
static EMSCRIPTEN_WEBSOCKET_T socket;
static EM_BOOL onopen(int eventType, const EmscriptenWebSocketOpenEvent* websocketEvent, void* userData) {
//code logic ...
return EM_TRUE;
}
static EM_BOOL onerror(int eventType, const EmscriptenWebSocketErrorEvent* websocketEvent, void* userData) {
//code logic ...
return EM_TRUE;
}
static EM_BOOL onclose(int eventType, const EmscriptenWebSocketCloseEvent* websocketEvent, void* userData) {
//code logic ...
return EM_TRUE;
}
static EM_BOOL onmessage(int eventType, const EmscriptenWebSocketMessageEvent* websocketEvent, void* userData) {
Yourclass* instance = reinterpret_cast<YourClass*>(userData);
//code logic ...
instance->YourNonStaticFunc(..);
return EM_TRUE;
}
#endif
In your .cpp Init/Method:
#ifdef __EMSCRIPTEN__
if (!emscripten_websocket_is_supported()) {
UE_LOG(LogTemp, Log, TEXT("\nemscripten_websocket not supoported :/\n"));
return;
}
EmscriptenWebSocketCreateAttributes ws_attrs = { TCHAR_TO_ANSI("ws://ip_address:port", NULL, EM_TRUE };
socket = emscripten_websocket_new(&ws_attrs);
emscripten_websocket_set_onopen_callback(socket, this, onopen);
emscripten_websocket_set_onerror_callback(socket, this, onerror);
emscripten_websocket_set_onclose_callback(socket, this, onclose);
emscripten_websocket_set_onmessage_callback(socket, this, onmessage);
#endif
For more about emscripten functions, you can check at: <Your engine install dir>/UE_4.23/Engine/Extras/ThirdPartyNotUE/emsdk/emscripten/1.38.31/system/include/emscripten/[websocket.h, emscripten.h, html5.h]

Arduino: pass function to class, returning String

I'm trying to get my Arduino class to return String messages with all kind of information for logging. With lots of trial and error I manage to pass a reference to the logging function to the class, but can only get a char* but not a String, and I want to be able to send Strings making it so much easier to send back all kinds of data.
I have the first part working already.
The sketch:
#include <Test.h>
#include <string.h>
void setup() {
Serial.begin(115200);
Test t;
t.setLogging(writeLog);
writeLog("Test message!" + String(" .... "));
t.doSomething("This is useful.");
t.doSomething("This as well.\n");
t.doSomething("This is even more useful.\n");
bool b = true;
}
void loop() {
}
void writeLog (char* message) {
Serial.print("char function: ");
Serial.print(message);
}
void writeLog (String message) {
Serial.print("String function: ");
Serial.println(message);
}
The header file:
#ifndef TEST_h
#define TEST_h
class Test
{
public:
Test(); // The constructor.
void setLogging(void (*)(char*)); // Takes function setting where to log.
void doSomething(char*);
};
#endif
The class:
#include <Test.h>
typedef void (*LogFunction)(char*);
LogFunction writeLog;
Test::Test () {
}
void Test::doSomething (char* s) {
// Do something useful and log the result.
writeLog(s);
}
void Test::setLogging (void (*f)(char*) ) {
writeLog = f;
return;
}
Now what I want my class to be able to do is send information like this, as String, rather than char* (I also haven't found an easy way of converting "anything" to char* and then concatenating the two or more strings):
writeLog ("HydroMonitorECSensor::setCalibration Receiving calibration - haveCalibration = " + String(haveCalibration));
writeLog ("HydroMonitorECSensor::setCalibration calibratedSlope = " + String(calibratedSlope));
writeLog ("HydroMonitorECSensor::setPins capPos set to " + String(capPos));
Where haveCalibration is a bool (which as String becomes either "true" or "false"), calibratedSlope is a double and capPos is an int. This way I can easily and cleanly send complete lines to the logger. Works great within the main script - not from the class.
I tried simply changing the char* to String and adding #include <string.h> to the library files but it doesn't work.
In Test.cpp I then get void Test::setLogging (void (*f)(String) ) { and in Test.h void setLogging(void (*)(String)); and now I get error messages:
In file included from /home/wouter/Arduino/libraries/Test/Test.cpp:1:0:
/home/wouter/Arduino/libraries/Test/Test.h:10:29: error: expected ',' or '...' before '(' token
void setLogging(void (*)(String)); // Takes function setting where to log.
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:40: error: variable or field 'setLogging' declared void
void Test::setLogging (void (*f)(String) ) {
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:31: error: 'f' was not declared in this scope
void Test::setLogging (void (*f)(String) ) {
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:34: error: 'String' was not declared in this scope
void Test::setLogging (void (*f)(String) ) {
^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
Suggestions?
Additional info, maybe important: I'm using the Arduino IDE and compile for ESP8266.
You are using the Arduino-provided String class, but didn't include the Arduino.h header in your test.h header file. That causes it to not find the String class and compilation fails.
The following works:
main.cpp:
#include <Arduino.h>
#include <test.hpp>
void writeLog (char* message);
void writeLog (String message);
void setup() {
Serial.begin(115200);
Test t;
t.setLogging(writeLog);
writeLog("Test message!" + String(" .... "));
t.doSomething("This is useful.");
t.doSomething("This as well.\n");
t.doSomething("This is even more useful.\n");
bool b = true;
}
void loop() {
}
void writeLog (char* message) {
Serial.print("char function: ");
Serial.print(message);
}
void writeLog (String message) {
Serial.print("String function: ");
Serial.println(message);
}
test.hpp:
#ifndef TEST_h
#define TEST_h
#include <Arduino.h> //for "String" class
//Typdef for the log function. Takes a String, returns nothing
typedef void (*LogFunction)(String);
class Test
{
public:
Test(); // The constructor.
// void setLogging(void (*)(char*)); // Takes function setting where to log.
void setLogging(LogFunction); //use the typedef here
void doSomething(char*);
};
#endif
test.cpp:
#include <test.hpp>
LogFunction writeLog;
Test::Test () {
}
void Test::doSomething (char* s) {
// Do something useful and log the result.
writeLog(s);
}
//void Test::setLogging (void (*f)(char*) ) {
void Test::setLogging (LogFunction f) { //also use typedef here
writeLog = f;
return;
}
Among other things that may arise, the compiler tells you that it cannot resolve identifier String.
This can have several reasons: First, you write String, and not string (note the capital letter in your writing). Second, if you write string and not std::string, it cannot be resolved unless you have either declared using namespace std (which is not the preferred variant for several reasons) or using std::string. Third, class std::string is declared in header <string>, which is something different than <string.h>.
So I'd write #include <string> and use then std::string.

error LNK2019 in implementing a C++ class for DLL

I implement a C++ class as DLL. But I have linker error when I interface to the dll. I have proper setup and not sure what is wrong. I researched, but can't find relevant solution, so I raise the query.
ASM_Lib.h
#ifdef EXPORT
#define DLLCLASS __declspec(dllexport)
#else
#define DLLCLASS __declspec(dllimport)
#endif
class ASM
{
public:
ASM();
~ASM();
int loadData(string path, string ext);
int landmarkEqualization();
private:
vector<PtsData_<CurrentType_>> pts;//this vector size is same as number of images, released after use
vector<string> files;//file names
vector<TrainingData_<CurrentType_>> td;//this vector size is same as number of images, released after use
vector<Mat> images;
};
extern "C" /*Important for avoiding Name decoration*/
{
DLLCLASS ASM* _cdecl CreateASMObject();
};
// Function Pointer Declaration of CreateASMObject() [Entry Point Function]
typedef ASM* (*CREATE_ASM) ();
ASM_Lib.cpp
namespace VIDEO_ANALYTICS_PLATFORM{
DLLCLASS ASM* _cdecl CreateASMObject() {
return new ASM();
}
ASM::ASM()
{
}
ASM::~ASM()
{
}
int ASM::loadData(string path, string ext)
{
return FILE_READ_WRITE_ERROR;
}
///*
//This loop equalize all landmark points to
//be equal distances
//*/
int ASM::landmarkEqualization()
{
//Clear vector
pts.clear();
vector<PtsData_<CurrentType_>>().swap(pts);
return SUCCESS;
}
}
Then in my test program, I interfaced as
#include "stdafx.h"
#include <iostream>
#include "ASM_Lib.h"
using namespace VIDEO_ANALYTICS_PLATFORM;
int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE hDLL = LoadLibrary(L"ASM_Lib.dll");
if (hDLL == NULL){
std::cout << "Failed to load library.\n";
}else{
CREATE_ASM pEntryFunction = (CREATE_ASM)GetProcAddress(hDLL, "CreateASMObject");
ASM* pASM = pEntryFunction();
if (pASM) {
pASM->loadData("C:\\PointsFiles", "pts");
}
FreeLibrary(hDLL);
}
std::cin.get();
return 0;
}
But I have LNK2019 link error (referenced in function wmain) and I don't have wmain. What could be the problem?
test.obj : error LNK2019: unresolved external symbol "public: int __cdecl VIDEO_ANALYTICS_PLATFORM::ASM::loadData(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?loadData#ASM#VIDEO_ANALYTICS_PLATFORM##QEAAHV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##0#Z) referenced in function wmain
If I comment out this API pASM->loadData("C:\\PointsFiles", "pts");, then it works and can load the dll properly.
EDIT:
Last update
ASM_Lib.h
#ifdef EXPORT
#define DLLCLASS __declspec(dllexport)
#else
#define DLLCLASS __declspec(dllimport)
#endif
namespace VIDEO_ANALYTICS_PLATFORM{
class i_ASM
{
public:
virtual ~i_ASM(){ ; };
virtual int loadData(string path, string ext)=0;
virtual int landmarkEqualization() = 0;
};
class ASM : public i_ASM
{
public:
ASM(){ }
int loadData(string path, string ext);
int landmarkEqualization();
private:
vector<PtsData_<CurrentType_>> pts;//this vector size is same as number of images, released after use
vector<string> files;//file names
vector<TrainingData_<CurrentType_>> td;//this vector size is same as number of images, released after use
vector<Mat> images;
};
extern "C"
{
DLLCLASS i_ASM* _cdecl CreateASMObject();
};
}
ASM_Lib.cpp
namespace VIDEO_ANALYTICS_PLATFORM{
DLLCLASS i_ASM* _cdecl CreateASMObject() {
return new ASM();
}
int ASM::loadData(string path, string ext)
{
return 0;
}
///*
//This loop equalize all landmark points to
//be equal distances
//*/
int ASM::landmarkEqualization()
{
//Clear vector
pts.clear();
vector<PtsData_<CurrentType_>>().swap(pts);
return SUCCESS;
}
}
Test.cpp
#include "ASM_Lib.h"
using namespace VIDEO_ANALYTICS_PLATFORM;
int _tmain(int argc, _TCHAR* argv[])
{
ASM* pASM = ::CreateASMObject();
if (pASM) {
pASM->loadData("C:\\PointsFiles", "pts");
pASM->~ASM();
pASM = NULL;
}
return 0;
}
I think, my last update should work. But still have linker error LNK2019 for both loadData() and ~ASM(). I did both test project and ASM_Lib project in the same solution. What could be wrong?
DLL exports only CreateASMObject function. ASM::loadData is not exported, but used in the test app.
I can propose 2 ways to fix:
1) Attribure with __declspec(dllexport) the whole ASM class or loadData member only, and add ASM_Lib.lib to test app project.
2) Declare pure abstract class (interface) IASM and change the return type of CreateASMObject:
class IASM
{
public:
virtual ~IASM() = 0;
virtual int loadData(string path, string ext) = 0;
};
extern "C"
{
DLLCLASS IASM* _cdecl CreateASMObject();
};
Then derive ASM from IASM and implement abstact methods (it may be done inside CPP file).
In this case linker does not need the address of loadData method, because it will be resolved in runtime via vtable.
PS. You must be sure that the DLL and its client use the same instance of heap manager (e.g. the same version of C runtime DLL). Otherwize it is unsafe to call delete for an object, created in another module. Solution is to add a method implementing deletion:
class IASM
{
public:
virtual void destroy() = 0;
protected:
~IMyAPI() = default;
};
class ASM: public IASM
{
public:
virtual void destroy() override
{
delete this;
}
};

c++ exception are not caught by catch(exception type)

Here is a piece of code that I have my exception in:
try {
hashTable->lookup(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo, dummyFrame);
}
catch (HashNotFoundException *e) {
}
catch (HashNotFoundException &e) {
}
catch (HashNotFoundException e) {
}
catch (...) {
}
Exception is generated within hashTable->lookup like that:
throw HashNotFoundException(file->filename(), pageNo);
Here is hashTable-lookup method signature
void BufHashTbl::lookup(const File* file, const PageId pageNo, FrameId &frameNo)
Exception escalates to top level like it's nobody's business.
I am using Mac(Lion) and Xcode(g++ for compiler)
Any thoughts would be appreciated.
Thanks!
We really need a complete example / further info to diagnose this for you.
For example the following version of the code compiles and works for me, outputing HashNotFoundException &
Note the code has some minor changes from your original, but they should not be material.
However it does generate the following warning:
example.cpp: In function ‘int main()’:
example.cpp:42: warning: exception of type ‘HashNotFoundException’ will be caught
example.cpp:38: warning: by earlier handler for ‘HashNotFoundException’
I'm compiling using i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00) on OS X 10.8.5
#include <iostream>
#include <sstream>
struct BadgerDbException {};
struct PageId {};
struct FrameId {};
struct HashNotFoundException : public BadgerDbException {
std::string name;
PageId pageNo;
HashNotFoundException(const std::string& nameIn, PageId pageNoIn)
: BadgerDbException(), name(nameIn), pageNo(pageNoIn) {
}
};
struct HashTable {
void lookup(void* file, const PageId pageNo, FrameId &frameNo) {
throw HashNotFoundException("a file", pageNo);
}
};
int main() {
HashTable * hashTable = new HashTable;
PageId a_Page_ID;
FrameId dummyFrame;
try {
FrameId dummyFrame;
hashTable->lookup(NULL, a_Page_ID, dummyFrame);
}
catch (HashNotFoundException *e) { std::cout<<"HashNotFoundException *"<<std::endl;}
catch (HashNotFoundException &e) { std::cout<<"HashNotFoundException &"<<std::endl;}
catch (HashNotFoundException e) { std::cout<<"HashNotFoundException"<<std::endl; }
catch (...) { std::cout<<"... exception"<<std::endl; }
}

C#.Net Calling a C++ DLL

I got a DLL(without the sourcecode) which exports like this:
?ReceiveCoreDataPtr##YAXPAX#Z
?xenoAddRigidBodyAngularImpulse##YAXHMMM#Z
?xenoAddRigidBodyForce##YAXHMMM#Z
?xenoAddRigidBodyForce##YAXHMMMMMM#Z
?xenoAddRigidBodyLinearImpulse##YAXHMMM#Z
?xenoAddRigidBodyPointImpulse##YAXHMMMMMM#Z
?xenoAddRigidBodyTorque##YAXHMMM#Z
?xenoCharacterControllerCrouch##YAXH#Z
?xenoCharacterControllerJump##YAXH#Z
?xenoCharacterDisable##YAXH#Z
?xenoCharacterEnable##YAXH#Z
?xenoDeleteRigidBody##YAXH#Z
?xenoEnd##YAXXZ
?xenoGetCameraFOV##YAKH#Z
?xenoGetCameraPointX##YAKH#Z
?xenoGetCameraPointY##YAKH#Z
?xenoGetCameraPointZ##YAKH#Z
?xenoGetCameraPositionX##YAKH#Z
?xenoGetCameraPositionY##YAKH#Z
?xenoGetCameraPositionZ##YAKH#Z
?xenoGetCharacterControllerHeadPosition##YAKH#Z
?xenoGetCharacterControllerPositionX##YAKH#Z
?xenoGetCharacterControllerPositionY##YAKH#Z
?xenoGetCharacterControllerPositionZ##YAKH#Z
?xenoGetCharacterControllerRotation##YAKH#Z
?xenoGetRigidBodyAllowedPenetrationDepth##YAKH#Z
?xenoGetRigidBodyAngularDamping##YAKH#Z
?xenoGetRigidBodyAngularVelocityX##YAKH#Z
?xenoGetRigidBodyAngularVelocityY##YAKH#Z
?xenoGetRigidBodyAngularVelocityZ##YAKH#Z
?xenoGetRigidBodyFriction##YAKH#Z
?xenoGetRigidBodyGravityFactor##YAKH#Z
?xenoGetRigidBodyLinearDamping##YAKH#Z
?xenoGetRigidBodyLinearVelocityX##YAKH#Z
?xenoGetRigidBodyLinearVelocityY##YAKH#Z
?xenoGetRigidBodyLinearVelocityZ##YAKH#Z
?xenoGetRigidBodyMass##YAKH#Z
?xenoGetRigidBodyMaxAngularVelocity##YAKH#Z
?xenoGetRigidBodyMaxLinearVelocity##YAKH#Z
?xenoGetRigidBodyPointVelocityX##YAKHMMM#Z
?xenoGetRigidBodyPointVelocityY##YAKHMMM#Z
?xenoGetRigidBodyPointVelocityZ##YAKHMMM#Z
?xenoGetRigidBodyRestitution##YAKH#Z
?xenoIsRigidBodyALadder##YAHH#Z
?xenoMakeCamera##YAXHH#Z
?xenoMakeCharacterController##YAXHMM#Z
?xenoMakeCharacterController##YAXHMMM#Z
?xenoMakeCharacterController##YAXHMMMM#Z
?xenoMakeCharacterController##YAXHMMMMM#Z
?xenoMakeCharacterController##YAXHMMMMMM#Z
?xenoMakeCharacterController##YAXHMMMMMMM#Z
?xenoMakeRigidBodyDynamicBox##YAXH#Z
?xenoMakeRigidBodyDynamicBox##YAXHM#Z
?xenoMakeRigidBodyDynamicCapsule##YAXH#Z
?xenoMakeRigidBodyDynamicCapsule##YAXHM#Z
?xenoMakeRigidBodyDynamicCylinder##YAXH#Z
?xenoMakeRigidBodyDynamicCylinder##YAXHM#Z
?xenoMakeRigidBodyDynamicSphere##YAXH#Z
?xenoMakeRigidBodyDynamicSphere##YAXHM#Z
?xenoMakeRigidBodyStaticBox##YAXH#Z
?xenoMakeRigidBodyStaticCapsule##YAXH#Z
?xenoMakeRigidBodyStaticCylinder##YAXH#Z
?xenoMakeRigidBodyStaticSphere##YAXH#Z
?xenoMakeRigidBodyStaticTriangleMesh##YAXH#Z
?xenoMakeVehicle##YAXHH#Z
?xenoMoveCharacterControllerBackward##YAXH#Z
?xenoMoveCharacterControllerForward##YAXH#Z
?xenoMoveCharacterControllerLeft##YAXH#Z
?xenoMoveCharacterControllerRight##YAXH#Z
?xenoSetCharacterControllerPosition##YAXHMMM#Z
?xenoSetCharacterControllerRotation##YAXHM#Z
?xenoSetGravity##YAXM#Z
?xenoSetGravity##YAXMMM#Z
?xenoSetRigidBodyAllowedPenetrationDepth##YAXHM#Z
?xenoSetRigidBodyAngularDamping##YAXHM#Z
?xenoSetRigidBodyAngularVelocity##YAXHMMM#Z
?xenoSetRigidBodyAsLadder##YAXHH#Z
?xenoSetRigidBodyFriction##YAXHM#Z
?xenoSetRigidBodyGravityFactor##YAXHM#Z
?xenoSetRigidBodyLinearDamping##YAXHM#Z
?xenoSetRigidBodyLinearVelocity##YAXHMMM#Z
?xenoSetRigidBodyMass##YAXHM#Z
?xenoSetRigidBodyMaxAngularVelocity##YAXHM#Z
?xenoSetRigidBodyMaxLinearVelocity##YAXHM#Z
?xenoSetRigidBodyPosition##YAXHMMM#Z
?xenoSetRigidBodyRestitution##YAXHM#Z
?xenoSetRigidBodyRotation##YAXHMMM#Z
?xenoSetTimeStep##YAXM#Z
?xenoStart##YAXH#Z
?xenoStart##YAXHM#Z
?xenoStart##YAXHMH#Z
?xenoStart##YAXXZ
?xenoUpdate##YAXXZ
?xenoVehicleAccelerate##YAXHM#Z
?xenoVehicleHandbrake##YAXH#Z
?xenoVehicleReverse##YAXH#Z
?xenoVehicleTurn##YAXHM#Z
When I try to use it in another C++ App like this
#include <windows.h>
class XenoPhysics
{
private:
typedef void (*FunctionFunc)(void);
typedef void (*FunctionFuncFloat)(float);
typedef void (*FunctionFuncInt)(int);
typedef void (*FunctionIntFloatFloatFloat)(int,float,float,float);
HMODULE libInstance;
public:
void LoadLib()
{
this->libInstance = LoadLibrary(L"F:\\xenophysics.dll");
}
void UnloadLib()
{
FreeLibrary(libInstance);
}
void xStart()
{
FunctionFunc curFunc;
curFunc = (FunctionFunc)GetProcAddress(this->libInstance, "?xenoStart##YAXXZ");
curFunc();
}
void xEnd()
{
FunctionFunc curFunc;
curFunc = (FunctionFunc)GetProcAddress(libInstance, "xenoEnd");
curFunc();
}
void xUpdate()
{
FunctionFunc curFunc;
curFunc = (FunctionFunc)GetProcAddress(libInstance, "xenoUpdate");
curFunc();
}
void xMakeRigidBodyStaticBox(int objid)
{
FunctionFuncInt curFunc;
curFunc = (FunctionFuncInt)GetProcAddress(libInstance, "xenoMakeRigidBodyStaticBox");
curFunc(objid);
}
void xMakeRigidBodyDynamicBox(int objid)
{
FunctionFuncInt curFunc;
curFunc = (FunctionFuncInt)GetProcAddress(libInstance, "xenoMakeRigidBodyDynamicBox");
curFunc(objid);
}
void xSetRigidBodyPosition(int objid, float x, float y, float z)
{
FunctionIntFloatFloatFloat curFunc;
curFunc = (FunctionIntFloatFloatFloat)GetProcAddress(libInstance, "xenoSetRigidBodyPosition");
curFunc(objid, x, y, z);
}
void xSetGravity(float grav)
{
FunctionFuncFloat curFunc;
curFunc = (FunctionFuncFloat)GetProcAddress(libInstance, "xenoSetGravity");
curFunc(grav);
}
};
This is the "wrapper"(or whatever you would call it) class.. To call the functions I'm doing
XenoPhysics * d = new XenoPhysics();
d->LoadLib();
d->xStart();
It then throws the following error at me(Note that it passes the LoadLib() without any errors)
Unhandled exception at 0x50261bc9 in Xeno Test.exe: 0xC0000005: Access violation reading location 0x00000064.
And yes; I've checked that the "curFunc" gets the address, not just a NULL pointer(atleast I think I've checked that)..
Anyone who can help out?
Edit: Forgot the C#.Net code, how stupid of me :3
Here is the C++ CLR DLL "wrapper" I tried to make:
#include <windows.h>
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the XENOWRAPPERWIN32_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// XENOWRAPPERWIN32_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef XENOWRAPPERWIN32_EXPORTS
#define XENOWRAPPERWIN32_API __declspec(dllexport)
#else
#define XENOWRAPPERWIN32_API __declspec(dllimport)
#endif
typedef void (*FunctionFunc)();
typedef void (*FunctionFuncFloat)(float);
typedef void (*FunctionFuncInt)(int);
typedef void (*FunctionIntFloatFloatFloat)(int,float,float,float);
// This class is exported from the xeno wrapper win32.dll
class XENOWRAPPERWIN32_API Cxenowrapperwin32 {
public:
Cxenowrapperwin32(void);
HINSTANCE libInstance;
// FunctionFunc curFunc;
// Library base functions
void LoadLib()
{
libInstance = LoadLibrary(L"F:\\xenophysics.dll");
}
void UnloadLib()
{
FreeLibrary(libInstance);
}
// Function calls to the xeno physics
void xStart()
{
FunctionFunc curFunc;
curFunc = (FunctionFunc)GetProcAddress(libInstance, "?xenoStart##YAXXZ");
curFunc();
}
void xEnd()
{
FunctionFunc curFunc;
curFunc = (FunctionFunc)GetProcAddress(libInstance, "?xenoEnd##YAXXZ");
curFunc();
}
void xUpdate()
{
FunctionFunc curFunc;
curFunc = (FunctionFunc)GetProcAddress(libInstance, "?xenoUpdate##YAXXZ");
curFunc();
}
void xMakeRigidBodyStaticBox(int objid)
{
FunctionFuncInt curFunc;
curFunc = (FunctionFuncInt)GetProcAddress(libInstance, "?xenoMakeRigidBodyStaticBox##YAXH#Z");
curFunc(objid);
}
void xMakeRigidBodyDynamicBox(int objid)
{
FunctionFuncInt curFunc;
curFunc = (FunctionFuncInt)GetProcAddress(libInstance, "?xenoMakeRigidBodyDynamicBox##YAXH#Z");
curFunc(objid);
}
void xSetRigidBodyPosition(int objid, float x, float y, float z)
{
FunctionIntFloatFloatFloat curFunc;
curFunc = (FunctionIntFloatFloatFloat)GetProcAddress(libInstance, "?xenoSetRigidBodyPosition##YAXHMMM#Z");
curFunc(objid, x, y, z);
}
void xSetGravity(float grav)
{
FunctionFuncFloat curFunc;
curFunc = (FunctionFuncFloat)GetProcAddress(libInstance, "?xenoSetGravity##YAXM#Z");
curFunc(grav);
}
};
extern XENOWRAPPERWIN32_API int nxenowrapperwin32;
XENOWRAPPERWIN32_API int fnxenowrapperwin32(void);
and here is how I use it in C#.Net
class xeno
{
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?LoadLib#Cxenowrapperwin32##QAEXXZ")]
public static extern void xLoadLib();
public void LoadLib()
{
xLoadLib();
}
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?UnloadLib#Cxenowrapperwin32##QAEXXZ")]
public static extern void xUnloadLib();
public void UnloadLib()
{
xUnloadLib();
}
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xStart#Cxenowrapperwin32##QAEXXZ")]
public static extern void xStart();
public void Start()
{
xStart();
}
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xUpdate#Cxenowrapperwin32##QAEXXZ")]
public static extern void xUpdate();
public void Update()
{
xUpdate();
}
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xEnd#Cxenowrapperwin32##QAEXXZ")]
public static extern void xEnd();
public void End()
{
xEnd();
}
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xMakeRigidBodyDynamicBox#Cxenowrapperwin32##QAEXH#Z")]
public static extern void xMakeRigidBodyDynamicBox(int objid);
public void MakeRigidBodyDynamicBox(int id)
{
xMakeRigidBodyDynamicBox(id);
}
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xMakeRigidBodyStaticBox#Cxenowrapperwin32##QAEXH#Z")]
public static extern void xMakeRigidBodyStaticBox(int objid);
public void MakeRigidBodyStaticBox(int id)
{
xMakeRigidBodyStaticBox(id);
}
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xSetGravity#Cxenowrapperwin32##QAEXM#Z")]
public static extern void xSetGravity(float grav);
public void SetGravity(float g)
{
xSetGravity(g);
}
[DllImport("C:\\Users\\hayer\\Documents\\Visual Studio 2008\\Projects\\xeno wrapper win32\\Debug\\xeno wrapper win32.dll", EntryPoint = "?xSetRigidBodyPosition#Cxenowrapperwin32##QAEXHMMM#Z")]
public static extern void xSetRigidBodyPosition(int obj, float x, float y, float z);
public void SetRigidBodyPosition(int id, float q, float w, float e)
{
xSetRigidBodyPosition(id, q, w, e);
}
}
And in the main C#.Net program I do
xeno tx = new xeno();
tx.Start();
tx.SetGravity(-1);
tx.MakeRigidBodyStaticBox(ground.Id);
tx.MakeRigidBodyDynamicBox(cube.Id);
tx.SetRigidBodyPosition(cube.Id, 0, 50, 0);
You must use proper calling conversion and parameters.