How can I call JNIEnv function from Kotlin/Native - java-native-interface

jni.h provide this
struct JNINativeInterface_ {
...
jint (JNICALL *GetVersion)(JNIEnv *env);
...
}
to call it in C can be written as
void test(JNIEnv *env){
// C
jint version = (*env)->GetVersion(env);
// C++
// jint version = env->GetVersion();
}
and then how can I do it in kotlin?
fun test(env: CPointer<JNIEnvVar>){
val version = // how?
}
After searching answer in google there are few example for Kotlin/Native with JNI but they're just basic example please help.
Thanks in advance.

Thanks to Michael.
Long answer is
fun test(env: CPointer<JNIEnvVar>){
// getting "JNINativeInterface_" reference from CPointer<JNIEnvVar> by
val jni:JNINativeInterface_ = env.pointed.pointed!!
// get function reference from JNINativeInterface_
// IntelliJ can help to find existing methods
val func = jni.GetVersion!!
// call a function
var version = func.invoke(env)
// above expression can be simplify as
version = env.pointed.pointed!!.GetVersion!!(env)!!
}
hope this can help somebody to understand
Kotlin/Native 🙂.

Related

Google Test/Mock Unit testing c++ - How to mock interface which has method with pointer?

I have an interface as follows:
class {
virtual bool display(char* name) = 0;
};
I have mocked this interface and during test I have added expect_call as follows:
char* name = "name";
EXPECT_CALL(mockHandler, display(testing::_))
.WillOnce(testing::DoAll(testing::SetArgPointee<0>(data), testing::Return(ErrorState::SERIAL_PORT_SUCCESS)));
But it is not working as expected. Any help would be really appreciated.
Any help would be really appreciated.
Refering code from http://google.github.io/googletest/gmock_cook_book.html could fix the issue. I was not giving arguments correctly to
.WillOnce(SetArrayArgument<0>(values, values + 5))

groovy: convert a list of interface implementation to a map with compileStatic

I am just a newer to groovy.
#Service
#CompileStatic
#Slf4j
class JourneyExecutionService {
#Autowired
List<DecisionEngineService> engineList;
Map<String, DecisionEngineService> engineMap;
void init(){
engineMap = engineList.collectEntries {[it.getIndex(), it]}
engineMap = engineList.stream().collect(Collectors.toMap(DecisionEngineService.getIndex, Functions.identity()))
}
The compile shows both statements in the init function fail due to the error:
Cannot assign 'Map<Object, Object>' to 'List<String, DecisionEngineService>'
and Cannot resolve symbol 'getIndex'
The 2nd statement in a java stream style.
The interface interface is like
interface DecisionEngineService {
String getIndex()
}
Can anyone helps fix the compileation issue?
Thanks
It should be enough to cast the map explicitly:
Map<String, DecisionEngineService> engineMap;
void init(){
engineMap = (Map<String, DecisionEngineService>)engineList.collectEntries {[it.index, it]}
}

Is it possible to create a new jobject of a java listener in JNI?

In Android Studio MainActivity, I write something like
int itemA_num = 0;
int itemB_num = 0;
ABCListener mabclistener = new ABCListenter() {
#Override
public void onEventActivated(CustomResult result) {
//do sth secret e.g.
itemA_num ++;
}
}
ABCobject mabcobject = (ABCobject) findviewById(R.id.abcobject1);
mabcobject.setListener(mabcListener);
I don't want people to decompile my APK and modify the code by amending the value or adding something like this:
ABCListener mabclistener = new ABCListenter() {
#Override
public void onEventActivated(CustomResult result) {
//do sth secret e.g.
itemA_num += 10000; //possibly some general name read by those guys and modified as int1 +=10000;
itemB_num += 500; //possibly some general name read by those guys and added this line int2 +=500;
}
}
So I want to use JNI with Cmake. Inside a .cpp file, I want to create the Class Object, findviewById, setListener and create the ABCListener.
I know using the format
jclass cls = (jclass) env->FindClass("abc/def/GHI");
jmethodID mid = (jmethod) env->GetMethodID(cls, "methodname", "(xxxx)yyy");
jobject obj = (jobject) env->CallObjectMethod(cls, mid, params);
However, if I want to write code about ABCListener and make a jobject of it, I don't know how and where to tell the machine I am going to write some code relating to #Override public void onEventActivated(CustomResult result) { ... }. I also want to add some lines of code inside the response in JNI.
I have found a website "similar" to this question but it is from 2011 and about Runnable. https://community.oracle.com/tech/developers/discussion/2298550/overriding-interface-methods-via-jni
I don't know if it still works in 2021.
First, define a new class on the Java side:
class NativeABCListener implements ABCListener {
#Override public native void onEventActivated(CustomResult result);
}
Next, create an instance of NativeABCListener, either in Java or in native code, and attach it to your mabcobject. You know how to do this so I will not repeat it.
On the native side, you simply define a C++ method with the appropriate name:
JNIEXPORT void JNICALL Java_your_package_NativeABCListener_onEventActivated(JNIEnv *env, jobject thiz, jobject result) {
...
}
If you need multiple ABCListeners that do different things, you can choose to create multiple NativeABCListener classes (each with their own corresponding native function), or you can modify NativeABCListener to store a C++ function pointer in a Java long field. In the ..._onEventActivated function you then extract the field from thiz and call it like a regular functino pointer.

WSDL imported with C++ Builder Wizard (C++ Builder Xe6 Pro)

i am pretty lame with using wsdl importer wizard with c++ Builder (XE6 Pro)
but finnally managed to properly import EBAY WSDL:
http://developer.ebay.com/webservices/latest/ebaySvc.wsdl
I can successfully run simple calls, but problem arises , when trying to set (or get )
Enum values.
At this point i am getting beautifull access violation after compilation.
Relevant piece of code:
void __fastcall TEbay::IndexBClick(TObject *Sender)
{
CallName="GetMyeBaySelling";
UnicodeString PUrl = MakeLink();
_di_eBayAPIInterface EbayCall = GeteBayAPIInterface(false,PUrl,HTP1);
CustomSecurityHeaderType *HDR = new RequesterCredentials;
HDR->eBayAuthToken=AuthToken;
HDR->Credentials = new UserIdPasswordType();
HDR->Credentials->AppId=AppId;
HDR->Credentials->DevId=DevId;
HDR->Credentials->AuthCert=CertId;
_di_ISOAPHeaders headers = EbayCall;
HTP1->SOAPHeaders->Send(HDR);
HTP1->SOAPHeaders->SetOwnsSentHeaders(True);
//GeteBayOfficialTimeRequest TR = new GeteBayOfficialTimeRequestType();
GetMyeBaySellingRequest *TR = new GetMyeBaySellingRequest();
GetMyeBaySellingResponse *ER =new GetMyeBaySellingResponse();
//ShowMessage(PUrl);
TR->Version=Version;
TR->ErrorLanguage="en_GB";
// This one raises error
TR->SoldList->OrderStatusFilter=OrderStatusFilterCodeType::All;
ShowMessage("2");
ER = EbayCall->GetMyeBaySelling(TR);
TDateTime ACK = ER->Timestamp->AsDateTime;
ShowMessage(UnicodeString("ODP:")+ACK);
// EbayCall->GeteBayOfficialTime(ER);
delete TR;
delete ER;
delete HDR;
}
Violation comes when i try to set up OrderStatusFilter or any enum values.
Declaration: (ebasvc.h) :
enum class OrderStatusFilterCodeType /* "urn:ebay:apis:eBLBaseComponents"[GblSmpl] */
{
All,
AwaitingPayment,
AwaitingShipment,
PaidAndShipped,
CustomCode
};
class OrderStatusFilterCodeType_TypeInfoHolder : public TObject {
OrderStatusFilterCodeType __instanceType;
public:
__published:
__property OrderStatusFilterCodeType __propType = { read=__instanceType };
};
I am getting mad allready with this, could anybody help me run this $#&^#$&^ ??
Best regards
TR->SoldList->OrderStatusFilter=OrderStatusFilterCodeType::All;
Looks like you are trying to assign a value to a property on the SoldList object, yet I can't see where you have created that object. Try the following.
TR->SoldList = new ItemListCustomizationType();
TR->SoldList->OrderStatusFilter=OrderStatusFilterCodeType::All;

CCCallFunc usage in cocos2dx

I am getting warning on this line stating that method actionWithTarget is deprecated.
Can any one tell which alternative method can be used in cocos2dx
CCCallFunc *callBackfunc = CCCallFunc::actionWithTarget(this,
callfunc_selector(GamePlay::startTrumphetAnimation));
Thanks
Try this:
CCCallFunc *func = CCCallFunc::create(this, callfunc_selector(GameOverScene::MyFunction));
//Declare this function also
void GameOverScene::MyFunction(CCObject* sender)
{
}
if you are using new version of Cocos2dx ,
auto funcCallAction = CallFunc::create([=](){
// TODO: do you stuff here
startTrumphetAnimation();
});
runAction(funcCallAction);
Try this
CCCallFunc *calFunc = CCCalFunc::create(this,callfunc_selector(ClassName::methodName));
If you are using cocos2dx v3:
CallFunc *calFunc = CalFunc::create(CC_CALLBACK_1(ClassName::methodName,this));
void ClassName::methodName(Ref* sender)
{
}
write function definition in this way
void GamePlay::startTrumphetAnimation(CCObject* sender)
{
}
If you are using COCOS2DX-3.0 or 3.14v
runAction( CallFunc::create([=]() { startTrumphetAnimation() }));
But you should write this line inside any method of GamePlay Class.