def getHeader(self, namespaceName): strHeader = """ #ifndef __%s__ #define __%s__ #include <iostream> #include <string> #include <string.h> #include <stdlib.h> #include <jni.h> """ % (namespaceName.upper(), namespaceName.upper()) # add the include for giws exception if configGiws().getThrowsException( ) and not namespaceName == configGiws().getExceptionFileName(): strHeader += """ #include "%s" """ % (configGiws().getExceptionFileName() + configGiws().getCPPHeaderExtension()) # Byte support strHeader += """ #if !defined(byte) | !defined(_MSC_VER) /* Defined anyway with Visual */ typedef signed char byte; #else #pragma message("Byte has been redefined elsewhere. Some problems can happen") #endif """ return strHeader
def getHeader(self, namespaceName): strHeader = """ #ifndef __%s__ #define __%s__ #include <iostream> #include <string> #include <string.h> #include <stdlib.h> #include <jni.h> """ % ( namespaceName.upper(), namespaceName.upper(), ) # add the include for giws exception if configGiws().getThrowsException() and not namespaceName == configGiws().getExceptionFileName(): strHeader += """ #include "%s" """ % ( configGiws().getExceptionFileName() + configGiws().getCPPHeaderExtension() ) # Byte support strHeader += """ #if defined(_MSC_VER) /* Defined anyway with Visual */ #include <Windows.h> #else typedef signed char byte; #endif """ return strHeader
def getHeader(self, namespaceName): strHeader = """ #ifndef __%s__ #define __%s__ #include <iostream> #include <string> #include <string.h> #include <stdlib.h> #include <jni.h> """ % (namespaceName.upper(), namespaceName.upper()) # add the include for giws exception if configGiws().getThrowsException( ) and not namespaceName == configGiws().getExceptionFileName(): strHeader += """ #include "%s" """ % (configGiws().getExceptionFileName() + configGiws().getCPPHeaderExtension()) # Byte support strHeader += """ #if defined(_MSC_VER) /* Defined anyway with Visual */ #include <Windows.h> #else typedef signed char byte; #endif """ return strHeader
def __errorMemoryByteBuffer(self, detachThread): # Management of the error when not enough memory to create the XXXXXBuffer if configGiws().getThrowsException(): errorMgntMemBis="""%sthrow %s::JniBadAllocException(curEnv);"""%(detachThread,configGiws().getExceptionFileName()) else: errorMgntMemBis="""std::cerr << "Could not convert C %s to Java UTF %s, memory full." << std::endl;%s exit(EXIT_FAILURE);"""%(self.getJavaBufferType(), self.getJavaBufferType(), detachThread) return errorMgntMemBis
def __errorMemoryString(self, detachThread): # Management of the error when not enought memory to create the string if configGiws().getThrowsException(): errorMgntMemBis="""%sthrow %s::JniBadAllocException(curEnv);"""%(detachThread,configGiws().getExceptionFileName()) else: errorMgntMemBis="""std::cerr << "Could not convert C string to Java UTF string, memory full." << std::endl;%s exit(EXIT_FAILURE);"""%(detachThread) return errorMgntMemBis
def __errorMemoryString(self, detachThread): # Management of the error when not enought memory to create the string if configGiws().getThrowsException(): errorMgntMemBis = """%sthrow %s::JniBadAllocException(curEnv);""" % ( detachThread, configGiws().getExceptionFileName()) else: errorMgntMemBis = """std::cerr << "Could not convert C string to Java UTF string, memory full." << std::endl;%s exit(EXIT_FAILURE);""" % (detachThread) return errorMgntMemBis
def specificPostProcessing(self, detachThread): """ needed to avoid casting issue with Visual (myArray[i]=(resultsArray[i] == JNI_TRUE);) """ if self.isArray(): str = JNIFrameWork().getExceptionCheckProfile(detachThread) strCommon = "" if configGiws().getDisableReturnSize() == True: strCommon += "int *lenRow;" strCommon += """ *lenRow = curEnv->GetArrayLength(res); jboolean isCopy = JNI_FALSE; """ if self.getDimensionArray() == 1: return ( str + strCommon + """ /* faster than getXXXArrayElements */ jboolean *resultsArray = static_cast<jboolean *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy)); bool * myArray= new bool[*lenRow]; for (jsize i = 0; i < *lenRow; i++){ myArray[i]=(resultsArray[i] == JNI_TRUE); } curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT); curEnv->DeleteLocalRef(res); """ ) else: if configGiws().getDisableReturnSize() == True: str += "int *lenCol;" return ( str + strCommon + """ bool ** myArray = new bool*[*lenRow]; for(int i=0; i<*lenRow; i++) { jbooleanArray oneDim = (jbooleanArray)curEnv->GetObjectArrayElement(res, i); *lenCol=curEnv->GetArrayLength(oneDim); bool *resultsArray = static_cast<bool *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy)); myArray[i] = new bool[*lenCol]; for(int j=0; j<*lenCol; j++) { myArray[i][j]=(resultsArray[j] == JNI_TRUE); } curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT); } curEnv->DeleteLocalRef(res); """ ) else: return ""
def __errorMemoryByteBuffer(self, detachThread): # Management of the error when not enough memory to create the XXXXXBuffer if configGiws().getThrowsException(): errorMgntMemBis = """%sthrow %s::JniBadAllocException(curEnv);""" % ( detachThread, configGiws().getExceptionFileName()) else: errorMgntMemBis = """std::cerr << "Could not convert C %s to Java UTF %s, memory full." << std::endl;%s exit(EXIT_FAILURE);""" % (self.getJavaBufferType(), self.getJavaBufferType(), detachThread) return errorMgntMemBis
def __getProfileCreationOfTheArray(self, varName, detachThread): """ When we deal with an array as input, we need to 'transform' it for Java""" javaType = self.getJavaTypeSyntaxForceNotArray() # removes the leading j and put the first char uppercase shortType = self.getJavaShortTypeForceNotArray() if configGiws().getThrowsException(): errorMgnt = """ if (%s_ == NULL) {%s // check that allocation succeed throw %s::JniBadAllocException(curEnv); } """ % (varName, detachThread, configGiws().getExceptionFileName()) errorMgntLocal = """ if (%sLocal == NULL) {%s // check that allocation succeed curEnv->DeleteLocalRef(%s_); throw %s::JniBadAllocException(curEnv); } """ % (varName, detachThread, varName, configGiws().getExceptionFileName()) else: errorMgnt = "" errorMgntLocal = "" if self.getDimensionArray() == 1: # Yep, it seems ugly to have that much varName but it is normal. return """ %sArray %s_ = curEnv->New%sArray( %sSize ) ; %s curEnv->Set%sArrayRegion( %s_, 0, %sSize, (%s*)(%s) ) ; """ % (javaType, varName, shortType, varName, errorMgnt, shortType, varName, varName, javaType, varName) else: return """ jobjectArray %s_ = curEnv->NewObjectArray(%sSize, curEnv->FindClass("[%s"),NULL); %s for (int i=0; i<%sSize; i++){ %sArray %sLocal = curEnv->New%sArray( %sSizeCol ) ; %s curEnv->Set%sArrayRegion( %sLocal, 0, %sSizeCol, (%s*)(%s[i]) ) ; curEnv->SetObjectArrayElement(%s_, i, %sLocal); curEnv->DeleteLocalRef(%sLocal); } """ % (varName, varName, self.getTypeSignature(), errorMgnt, varName, javaType, varName, shortType, varName, errorMgntLocal, shortType, varName, varName, javaType, varName, varName, varName, varName)
def getEndSynchronizeMethod(self,objectName): myStr=""" void %s::endSynchronize() { if ( getCurrentEnv()->MonitorExit(instance) != JNI_OK) { """%(objectName) if configGiws().getThrowsException(): myStr+="""throw %s::JniMonitorException(getCurrentEnv(), "%s");"""%(configGiws().getExceptionFileName(),objectName) else: myStr+= """ std::cerr << "Fail to exit monitor." << std::endl; exit(EXIT_FAILURE);""" return myStr + """
def getMethodIdProfile(self, method): params = "" for parameter in method.getParameters(): if parameter.getType().isArray() and not parameter.getType( ).isByteBufferBased(): # It is an array params += "[" * parameter.getType().getDimensionArray() params += parameter.getType().getTypeSignature() methodIdName = method.getUniqueNameOfTheMethod() getMethod = "" firstParam = "" signatureReturn = method.getReturn().getTypeSignature() if method.getReturn().isArray() and not method.getReturn( ).isByteBufferBased(): # Returns an array ... signatureReturn = "[" * method.getReturn().getDimensionArray( ) + signatureReturn if method.getModifier() == "static": getMethod = "GetStaticMethodID" firstParam = "cls" else: getMethod = "GetMethodID" firstParam = "this->instanceClass" if method.getModifier() == "static": methodCall = "static jmethodID" else: methodCall = """if (%s==NULL) { /* Use the cache */ """ % methodIdName # Management of the error if configGiws().getThrowsException(): errorMgnt = """%sthrow %s::JniMethodNotFoundException(curEnv, "%s");""" % ( method.getDetachThread(), configGiws().getExceptionFileName(), method.getName()) else: errorMgnt = """std::cerr << "Could not access to the method " << "%s" << std::endl; curEnv->ExceptionDescribe(); %s exit(EXIT_FAILURE);""" % (method.getName(), method.getDetachThread()) methodIdProfile = """ %s %s = curEnv->%s(%s, "%s", "(%s)%s" ) ; if (%s == NULL) { %s } """ % (methodCall, methodIdName, getMethod, firstParam, method.getName(), params, signatureReturn, methodIdName, errorMgnt) if method.getModifier() != "static": methodIdProfile += "}" # Cached methodId return methodIdProfile
def getExceptionCheckProfile(self, detachThread, methodReturn=""): if configGiws().getThrowsException(): str="""if (curEnv->ExceptionCheck()) { """ if methodReturn != "": str+="""delete[] %s; """%(methodReturn) str+= """%sthrow %s::JniCallMethodException(curEnv); }"""%(detachThread,configGiws().getExceptionFileName()) return str else: return """if (curEnv->ExceptionCheck()) {
def getExceptionCheckProfile(self, detachThread, methodReturn=""): if configGiws().getThrowsException(): str = """if (curEnv->ExceptionCheck()) { """ if methodReturn != "": str += """delete[] %s; """ % (methodReturn) str += """%sthrow %s::JniCallMethodException(curEnv); }""" % (detachThread, configGiws().getExceptionFileName()) return str else: return """if (curEnv->ExceptionCheck()) {
def __getConstructorWhichUsesAnAlreadyExistingJObject(self): ### Init the list of the cache of methodID strMethodID = self.__getDeclarationOfCachingMethodID() # Management of the error when the instance class could not be created a global ref if configGiws().getThrowsException(): errorMgntRef = """throw %s::JniObjectCreationException(curEnv, this->className());""" % ( configGiws().getExceptionFileName()) else: errorMgntRef = """ std::cerr << "Could not create a Global Ref of " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when the instance class could not be created a global ref if configGiws().getThrowsException(): errorMgntNewRef = """throw %s::JniObjectCreationException(curEnv, this->className());""" % ( configGiws().getExceptionFileName()) else: errorMgntNewRef = """ std::cerr << "Could not create a new global ref of " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" constructorProfile = """%s::%s""" % ( self.getName(), self.__getConstructorProfileWhichUsesAnAlreadyExistingJObject()) if self.getExtendedClass() != None: constructorProfile += """ : %s(fakeGiwsDataType::fakeGiwsDataType()) """ % ( self.getExtendedClass().getName()) return """ %s { jvm=jvm_; JNIEnv * curEnv = getCurrentEnv(); jclass localClass = curEnv->GetObjectClass(JObj); this->instanceClass = static_cast<jclass>(curEnv->NewGlobalRef(localClass)); curEnv->DeleteLocalRef(localClass); if (this->instanceClass == NULL) { %s } this->instance = curEnv->NewGlobalRef(JObj) ; if(this->instance == NULL){ %s } /* Methods ID set to NULL */ %s } """ % (constructorProfile, errorMgntRef, errorMgntNewRef, strMethodID)
def __getProfileCreationOfTheArray(self, varName, detachThread): """ When we deal with an array as input, we need to 'transform' it for Java""" javaType=self.getJavaTypeSyntaxForceNotArray() # removes the leading j and put the first char uppercase shortType=self.getJavaShortTypeForceNotArray() if configGiws().getThrowsException(): errorMgnt=""" if (%s_ == NULL) {%s // check that allocation succeed throw %s::JniBadAllocException(curEnv); } """%(varName,detachThread,configGiws().getExceptionFileName()) errorMgntLocal=""" if (%sLocal == NULL) {%s // check that allocation succeed curEnv->DeleteLocalRef(%s_); throw %s::JniBadAllocException(curEnv); } """%(varName, detachThread, varName, configGiws().getExceptionFileName()) else: errorMgnt="" errorMgntLocal="" if self.getDimensionArray() == 1: # Yep, it seems ugly to have that much varName but it is normal. return """ %sArray %s_ = curEnv->New%sArray( %sSize ) ; %s curEnv->Set%sArrayRegion( %s_, 0, %sSize, (%s*)(%s) ) ; """%(javaType, varName, shortType, varName, errorMgnt, shortType, varName, varName, javaType, varName) else: return """ jobjectArray %s_ = curEnv->NewObjectArray(%sSize, curEnv->FindClass("[%s"),NULL); %s for (int i=0; i<%sSize; i++){ %sArray %sLocal = curEnv->New%sArray( %sSizeCol ) ; %s curEnv->Set%sArrayRegion( %sLocal, 0, %sSizeCol, (%s*)(%s[i]) ) ; curEnv->SetObjectArrayElement(%s_, i, %sLocal); curEnv->DeleteLocalRef(%sLocal); } """%(varName, varName, self.getTypeSignature(), errorMgnt, varName, javaType, varName, shortType, varName, errorMgntLocal, shortType, varName, varName, javaType, varName, varName, varName, varName)
def specificPostProcessing(self, detachThread): """ needed to avoid casting issue with Visual (myArray[i]=(resultsArray[i] == JNI_TRUE);) """ if self.isArray(): str=JNIFrameWork().getExceptionCheckProfile(detachThread) strCommon="" if configGiws().getDisableReturnSize()==True: strCommon+="int *lenRow;" strCommon+=""" *lenRow = curEnv->GetArrayLength(res); jboolean isCopy = JNI_FALSE; """ if self.getDimensionArray() == 1: return str+strCommon+""" /* faster than getXXXArrayElements */ jboolean *resultsArray = static_cast<jboolean *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy)); bool * myArray= new bool[*lenRow]; for (jsize i = 0; i < *lenRow; i++){ myArray[i]=(resultsArray[i] == JNI_TRUE); } curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT); curEnv->DeleteLocalRef(res); """ else: if configGiws().getDisableReturnSize()==True: str+="int *lenCol;" return str+strCommon+""" bool ** myArray = new bool*[*lenRow]; for(int i=0; i<*lenRow; i++) { jbooleanArray oneDim = (jbooleanArray)curEnv->GetObjectArrayElement(res, i); *lenCol=curEnv->GetArrayLength(oneDim); bool *resultsArray = static_cast<bool *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy)); myArray[i] = new bool[*lenCol]; for(int j=0; j<*lenCol; j++) { myArray[i][j]=(resultsArray[j] == JNI_TRUE); } curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT); } curEnv->DeleteLocalRef(res); """ else: return ""
def getStaticProfile(self): static = """ JNIEnv * curEnv = NULL; jvm_->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL); jclass cls = initClass(curEnv); if ( cls == NULL) { """ # Management of the error if configGiws().getThrowsException(): errorMgnt = """throw %s::JniCallMethodException(curEnv);""" % (configGiws().getExceptionFileName()) else: errorMgnt = """std::cerr << "Could not access to the class " << className() << std::endl; exit(EXIT_FAILURE);""" return static + errorMgnt + """
def generateCXXBody(self, className): """ Generates the content of the method ... for the body """ baseProfile = """%s %s::%s""" % (self.getReturn().getNativeType(), className, self.getName()) ret = "" if self.getReturn().isArray() and configGiws().getDisableReturnSize() != True: if len(self.__parameters) != 0: ret += ", " if self.getReturn().getDimensionArray() == 1: ret += "int *lenRow" else: ret += "int *lenRow, int *lenCol" str = """ %s (%s%s)""" % ( baseProfile, self.getParametersCXX(), ret, ) str += """{ %s }""" % ( self.__createMethodBody() ) return str
def generateCXXHeader(self): """ Generates the profile of the method ... for the header """ if self.getModifier() == "static": static = "static " else: static = "" ret = "" if self.getReturn().isArray() and configGiws().getDisableReturnSize() != True: if len(self.__parameters) != 0: ret += ", " if self.getReturn().getDimensionArray() == 1: ret += "int *lenRow" else: ret += "int *lenRow, int *lenCol" str = """%s%s %s(%s%s); """ % ( static, self.getReturn().getNativeType(), self.getName(), self.getParametersCXX(), ret, ) return str
def __getConstructorWhichUsesAnAlreadyExistingJObject(self): ### Init the list of the cache of methodID strMethodID=self.__getDeclarationOfCachingMethodID() # Management of the error when the instance class could not be created a global ref if configGiws().getThrowsException(): errorMgntRef="""throw %s::JniObjectCreationException(curEnv, this->className());"""%(configGiws().getExceptionFileName()) else: errorMgntRef=""" std::cerr << "Could not create a Global Ref of " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when the instance class could not be created a global ref if configGiws().getThrowsException(): errorMgntNewRef="""throw %s::JniObjectCreationException(curEnv, this->className());"""%(configGiws().getExceptionFileName()) else: errorMgntNewRef=""" std::cerr << "Could not create a new global ref of " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" constructorProfile="""%s::%s"""%(self.getName(), self.__getConstructorProfileWhichUsesAnAlreadyExistingJObject()) if self.getExtendedClass()!=None: constructorProfile+=""" : %s(fakeGiwsDataType::fakeGiwsDataType()) """ % (self.getExtendedClass().getName()) return """ %s { jvm=jvm_; JNIEnv * curEnv = getCurrentEnv(); jclass localClass = curEnv->GetObjectClass(JObj); this->instanceClass = static_cast<jclass>(curEnv->NewGlobalRef(localClass)); curEnv->DeleteLocalRef(localClass); if (this->instanceClass == NULL) { %s } this->instance = curEnv->NewGlobalRef(JObj) ; if(this->instance == NULL){ %s } /* Methods ID set to NULL */ %s } """%(constructorProfile, errorMgntRef, errorMgntNewRef, strMethodID)
def getMethodGetCurrentEnv(self,objectName): if configGiws().getThrowsException(): error = """throw %s::JniException(getCurrentEnv());"""%(configGiws().getExceptionFileName()) else: error = """std::cerr << "Could not retrieve the current JVM." << std::endl; exit(EXIT_FAILURE); """ return """ JNIEnv * %s::getCurrentEnv() { JNIEnv * curEnv = NULL; jint res=this->jvm->AttachCurrentThread(reinterpret_cast<void **>(&curEnv), NULL); if (res != JNI_OK) { %s } return curEnv; }"""%(objectName, error)
def getMethodIdProfile(self, method): params="" for parameter in method.getParameters(): if parameter.getType().isArray() and not parameter.getType().isByteBufferBased(): # It is an array params+="[" * parameter.getType().getDimensionArray() params+=parameter.getType().getTypeSignature() methodIdName=method.getUniqueNameOfTheMethod() signatureReturn=method.getReturn().getTypeSignature() if method.getReturn().isArray() and not method.getReturn().isByteBufferBased(): # Returns an array ... signatureReturn="["* method.getReturn().getDimensionArray() + signatureReturn if method.getModifier()=="static": getMethod = "GetStaticMethodID" firstParam = "cls" else: getMethod = "GetMethodID" firstParam = "this->instanceClass" if method.getModifier()=="static": methodCall="static jmethodID" else: methodCall="""if (%s==NULL) { /* Use the cache */ """%methodIdName # Management of the error if configGiws().getThrowsException(): errorMgnt="""%sthrow %s::JniMethodNotFoundException(curEnv, "%s");"""%(method.getDetachThread(),configGiws().getExceptionFileName(),method.getName()) else: errorMgnt="""std::cerr << "Could not access to the method " << "%s" << std::endl; curEnv->ExceptionDescribe(); %s exit(EXIT_FAILURE);"""%(method.getName(),method.getDetachThread()) methodIdProfile=""" %s %s = curEnv->%s(%s, "%s", "(%s)%s" ) ; if (%s == NULL) { %s } """%(methodCall, methodIdName, getMethod, firstParam, method.getName(), params,signatureReturn, methodIdName, errorMgnt) if method.getModifier()!="static": methodIdProfile+="}" # Cached methodId return methodIdProfile
def generateCXXHeader(self): """ Generates the profile of the method ... for the header """ if self.getModifier() == "static": static = "static " else: static = "" ret = "" if self.getReturn().isArray( ) and configGiws().getDisableReturnSize() != True: if len(self.__parameters) != 0: ret += ", " if self.getReturn().getDimensionArray() == 1: ret += "int *lenRow" else: ret += "int *lenRow, int *lenCol" str = """%s%s %s(%s%s); """ % (static, self.getReturn().getNativeType(), self.getName(), self.getParametersCXX(), ret) return str
def getParametersCXX(self): """ Returns the parameters with their types """ i=1 if self.getModifier()=="static": str="JavaVM * jvm_" if len(self.__parameters)!=0: str+=", " else: # In the case where there is no input argument # but return an array of int (or an other type) # needed to lenRow if self.getReturn().isArray() and configGiws().getDisableReturnSize()!=True: str+=", " else: str="" for parameter in self.__parameters: str=str+parameter.generateCXXHeader() if len(self.__parameters)!=i: str+=", " i=i+1 return str
def generateCXXBody(self, className): """ Generates the content of the method ... for the body """ baseProfile = """%s %s::%s""" % (self.getReturn().getNativeType(), className, self.getName()) ret = "" if self.getReturn().isArray( ) and configGiws().getDisableReturnSize() != True: if len(self.__parameters) != 0: ret += ", " if self.getReturn().getDimensionArray() == 1: ret += "int *lenRow" else: ret += "int *lenRow, int *lenCol" str = """ %s (%s%s)""" % (baseProfile, self.getParametersCXX(), ret) str += """{ %s }""" % (self.__createMethodBody()) return str
def getParametersCXX(self): """ Returns the parameters with their types """ i = 1 if self.getModifier() == "static": str = "JavaVM * jvm_" if len(self.__parameters) != 0: str += ", " else: # In the case where there is no input argument # but return an array of int (or an other type) # needed to lenRow if self.getReturn().isArray( ) and configGiws().getDisableReturnSize() != True: str += ", " else: str = "" for parameter in self.__parameters: str = str + parameter.generateCXXHeader() if len(self.__parameters) != i: str += ", " i = i + 1 return str
def specificPreProcessing(self, parameter, detachThread): """ Overrides the preprocessing of the array """ name = parameter.getName() # Management of the error when not enought memory to create the string if configGiws().getThrowsException(): errorMgntMem = """%sthrow %s::JniBadAllocException(curEnv);""" % ( detachThread, configGiws().getExceptionFileName()) else: errorMgntMem = """std::cerr << "Could not allocate Java string array, memory full." << std::endl;%s exit(EXIT_FAILURE);""" % (detachThread) errorMgntMemBis = self.__errorMemoryString(detachThread) if self.isArray(): if self.getDimensionArray() == 1: return """ // create java array of strings. jobjectArray %s_ = curEnv->NewObjectArray( %sSize, stringArrayClass, NULL); if (%s_ == NULL) { %s } // convert each char * to java strings and fill the java array. for ( int i = 0; i < %sSize; i++) { jstring TempString = curEnv->NewStringUTF( %s[i] ); if (TempString == NULL) { %s } curEnv->SetObjectArrayElement( %s_, i, TempString); // avoid keeping reference on too many strings curEnv->DeleteLocalRef(TempString); }""" % (name, name, name, errorMgntMem, name, name, errorMgntMemBis, name) else: return """ // create java array of array of strings. jobjectArray %s_ = curEnv->NewObjectArray( %sSize, curEnv->FindClass("[Ljava/lang/String;"), NULL); if (%s_ == NULL) { %s } for ( int i = 0; i < %sSize; i++) { jobjectArray %sLocal = curEnv->NewObjectArray( %sSizeCol, stringArrayClass, NULL); // convert each char * to java strings and fill the java array. for ( int j = 0; j < %sSizeCol; j++) { jstring TempString = curEnv->NewStringUTF( %s[i][j] ); if (TempString == NULL) { %s } curEnv->SetObjectArrayElement( %sLocal, j, TempString); // avoid keeping reference on too many strings curEnv->DeleteLocalRef(TempString); } curEnv->SetObjectArrayElement(%s_, i, %sLocal); curEnv->DeleteLocalRef(%sLocal); }""" % (name, name, name, errorMgntMem, name, name, name, name, name, errorMgntMemBis, name, name, name, name) else: # Need to store is for the post processing (delete) self.parameterName = name tempName = name + "_" return """ jstring %s = curEnv->NewStringUTF( %s ); if (%s != NULL && %s == NULL) { %s } """ % (tempName, name, name, tempName, errorMgntMemBis)
def specificPostProcessing(self, detachThread): """ Called when we are returning a string or an array of string """ # We are doing an exception check here JUST in this case because # in methodGiws::__createMethodBody we usually do it at the end # of the method just after deleting the variable # but when dealing with string, in this method, we are calling some # methods which override the "exception engine" which drive the JNI # engine crazy. str=JNIFrameWork().getExceptionCheckProfile(detachThread) str=str+"if (res != NULL) { " if self.isArray(): strCommon="" strDeclaration="" if configGiws().getDisableReturnSize()==True: strCommon+="int lenRow;" else: # The size of the array is returned as output argument of the function strDeclaration="*" strCommon+=""" %s lenRow = curEnv->GetArrayLength(res); """%(strDeclaration) self.temporaryVariableName="arrayOfString" if self.getDimensionArray() == 1: str+=strCommon+""" char **arrayOfString; arrayOfString = new char *[%slenRow]; for (jsize i = 0; i < %slenRow; i++){ jstring resString = reinterpret_cast<jstring>(curEnv->GetObjectArrayElement(res, i)); const char *tempString = curEnv->GetStringUTFChars(resString, 0); arrayOfString[i] = new char[strlen(tempString) + 1]; strcpy(arrayOfString[i], tempString); curEnv->ReleaseStringUTFChars(resString, tempString); curEnv->DeleteLocalRef(resString); } """%(strDeclaration, strDeclaration) return str else: if configGiws().getDisableReturnSize()==True: str+="int lenCol;" str+=strCommon+""" char ***arrayOfString; arrayOfString = new char **[%slenRow]; for (jsize i = 0; i < %slenRow; i++){ /* Line of the array */ jobjectArray resStringLine = reinterpret_cast<jobjectArray>(curEnv->GetObjectArrayElement(res, i)); %slenCol = curEnv->GetArrayLength(resStringLine); arrayOfString[i]=new char*[%slenCol]; for (jsize j = 0; j < %slenCol; j++){ jstring resString = reinterpret_cast<jstring>(curEnv->GetObjectArrayElement(resStringLine, j)); const char *tempString = curEnv->GetStringUTFChars(resString, 0); arrayOfString[i][j] = new char[strlen(tempString) + 1]; strcpy(arrayOfString[i][j], tempString); curEnv->ReleaseStringUTFChars(resString, tempString); curEnv->DeleteLocalRef(resString); } curEnv->DeleteLocalRef(resStringLine); } """%(strDeclaration, strDeclaration, strDeclaration, strDeclaration, strDeclaration) return str else: if hasattr(self,"parameterName"): str+="""curEnv->DeleteLocalRef(%s);"""%(self.parameterName+"_") str=str+""" const char *tempString = curEnv->GetStringUTFChars(res, 0); char * %s = new char[strlen(tempString) + 1]; strcpy(%s, tempString); curEnv->ReleaseStringUTFChars(res, tempString); curEnv->DeleteLocalRef(res); """%(self.temporaryVariableName, self.temporaryVariableName) return str
def specificPostProcessing(self, detachThread): """ Called when we are returning a string or an array of string """ # We are doing an exception check here JUST in this case because # in methodGiws::__createMethodBody we usually do it at the end # of the method just after deleting the variable # but when dealing with string, in this method, we are calling some # methods which override the "exception engine" which drive the JNI # engine crazy. str = JNIFrameWork().getExceptionCheckProfile(detachThread) str = str + "if (res != NULL) { " if self.isArray(): strCommon = "" strDeclaration = "" if configGiws().getDisableReturnSize() == True: strCommon += "int lenRow;" else: # The size of the array is returned as output argument of the function strDeclaration = "*" strCommon += """ %s lenRow = curEnv->GetArrayLength(res); """ % (strDeclaration) self.temporaryVariableName = "arrayOfString" if self.getDimensionArray() == 1: str += strCommon + """ char **arrayOfString; arrayOfString = new char *[%slenRow]; for (jsize i = 0; i < %slenRow; i++){ jstring resString = reinterpret_cast<jstring>(curEnv->GetObjectArrayElement(res, i)); const char *tempString = curEnv->GetStringUTFChars(resString, 0); arrayOfString[i] = new char[strlen(tempString) + 1]; strcpy(arrayOfString[i], tempString); curEnv->ReleaseStringUTFChars(resString, tempString); curEnv->DeleteLocalRef(resString); } """ % (strDeclaration, strDeclaration) return str else: if configGiws().getDisableReturnSize() == True: str += "int lenCol;" str += strCommon + """ char ***arrayOfString; arrayOfString = new char **[%slenRow]; for (jsize i = 0; i < %slenRow; i++){ /* Line of the array */ jobjectArray resStringLine = reinterpret_cast<jobjectArray>(curEnv->GetObjectArrayElement(res, i)); %slenCol = curEnv->GetArrayLength(resStringLine); arrayOfString[i]=new char*[%slenCol]; for (jsize j = 0; j < %slenCol; j++){ jstring resString = reinterpret_cast<jstring>(curEnv->GetObjectArrayElement(resStringLine, j)); const char *tempString = curEnv->GetStringUTFChars(resString, 0); arrayOfString[i][j] = new char[strlen(tempString) + 1]; strcpy(arrayOfString[i][j], tempString); curEnv->ReleaseStringUTFChars(resString, tempString); curEnv->DeleteLocalRef(resString); } curEnv->DeleteLocalRef(resStringLine); } """ % (strDeclaration, strDeclaration, strDeclaration, strDeclaration, strDeclaration) return str else: if hasattr(self, "parameterName"): str += """curEnv->DeleteLocalRef(%s);""" % ( self.parameterName + "_") str = str + """ const char *tempString = curEnv->GetStringUTFChars(res, 0); char * %s = new char[strlen(tempString) + 1]; strcpy(%s, tempString); curEnv->ReleaseStringUTFChars(res, tempString); curEnv->DeleteLocalRef(res); """ % (self.temporaryVariableName, self.temporaryVariableName) return str
def __getConstructorWhichInstanciateTheNewObject(self): """ """ # Management of the error when the class cannot be found if configGiws().getThrowsException(): errorMgntClass = """ throw %s::JniClassNotFoundException(curEnv, this->className());""" % ( configGiws().getExceptionFileName()) else: errorMgntClass = """std::cerr << "Could not get the Class " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when the global ref could not be created if configGiws().getThrowsException(): errorMgntCreation = """throw %s::JniObjectCreationException(curEnv, this->className());""" % ( configGiws().getExceptionFileName()) else: errorMgntCreation = """std::cerr << "Could not create a Global Ref of " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when it is not possible to retrieve the constructor if configGiws().getThrowsException(): errorMgntConstructor = """throw %s::JniObjectCreationException(curEnv, this->className());""" % ( configGiws().getExceptionFileName()) else: errorMgntConstructor = """std::cerr << "Could not retrieve the constructor of the class " << this->className() << " with the profile : " << construct << param << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when it is not possible instantiate the obj if configGiws().getThrowsException(): errorMgntInstantiate = """throw %s::JniObjectCreationException(curEnv, this->className());""" % ( configGiws().getExceptionFileName()) else: errorMgntInstantiate = """std::cerr << "Could not instantiate the object " << this->className() << " with the constructor : " << construct << param << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when it is not possible create a global ref if configGiws().getThrowsException(): errorMgntRef = """throw %s::JniObjectCreationException(curEnv, this->className());""" % ( configGiws().getExceptionFileName()) else: errorMgntRef = """std::cerr << "Could not create a new global ref of " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" ### Init the list of the cache of methodID strMethodID = self.__getDeclarationOfCachingMethodID() constructorProfile = """%s::%s""" % ( self.getName(), self.__getConstructorProfileWhichInstanciateTheNewObject()) if self.getExtendedClass() != None: constructorProfile += """ : %s(fakeGiwsDataType::fakeGiwsDataType())""" % ( self.getExtendedClass().getName()) return """%s { jmethodID constructObject = NULL ; jobject localInstance ; jclass localClass ; const std::string construct="<init>"; const std::string param="()V"; jvm=jvm_; JNIEnv * curEnv = getCurrentEnv(); localClass = curEnv->FindClass( this->className().c_str() ) ; if (localClass == NULL) { %s } this->instanceClass = static_cast<jclass>(curEnv->NewGlobalRef(localClass)); /* localClass is not needed anymore */ curEnv->DeleteLocalRef(localClass); if (this->instanceClass == NULL) { %s } constructObject = curEnv->GetMethodID( this->instanceClass, construct.c_str() , param.c_str() ) ; if(constructObject == NULL){ %s } localInstance = curEnv->NewObject( this->instanceClass, constructObject ) ; if(localInstance == NULL){ %s } this->instance = curEnv->NewGlobalRef(localInstance) ; if(this->instance == NULL){ %s } /* localInstance not needed anymore */ curEnv->DeleteLocalRef(localInstance); /* Methods ID set to NULL */ %s } """ % (constructorProfile, errorMgntClass, errorMgntCreation, errorMgntConstructor, errorMgntInstantiate, errorMgntRef, strMethodID)
# The fact that you are presently reading this means that you have had # knowledge of the CeCILL license and that you accept its terms. # # For more information, see the file COPYING from distutils.core import setup from configGiws import configGiws import os root_dir = os.path.dirname(__file__) if root_dir: os.chdir(root_dir) setup(name="giws", description="Generate C++ class wrappers to call Java methods/objects", version=configGiws().getVersion(), author="Sylvestre Ledru", author_email="*****@*****.**", url="http://www.scilab.org/giws/", packages=['.', 'classRepresentation', 'datatypes'], scripts=['giws'], license="CeCILL", long_description= """Giws is basically doing the same stuff as SWIG but the opposite. Calling Java from C/C++ can be tricky: JNI calls are complicated especially when dealing with non primivite types or arrays, performance issues must be kept in mind all the time, the code can be redundant (checking exceptions, checking returns of operations...). Giws hides this complexity through a C++ class which wraps the Java class.""")
def specificPostProcessing(self, detachThread): """ Called when we are returning a XXXXXBuffer or an array of XXXBuffer TODO """ # We are doing an exception check here JUST in this case because # in methodGiws::__createMethodBody we usually do it at the end # of the method just after deleting the variable # but when dealing with DoubleBuffer, in this method, we are calling some # methods which override the "exception engine" which drive the JNI # engine crazy. TODO check str=JNIFrameWork().getExceptionCheckProfile(detachThread) if self.isArray(): strCommon="" strDeclaration="" if configGiws().getDisableReturnSize()==True: strCommon+="int lenRow;" else: # The size of the array is returned as output argument of the function strDeclaration="*" self.temporaryVariableName="byteBufferRes" if self.getDimensionArray() == 1: str+=strCommon+""" *lenRow = curEnv->GetDirectBufferCapacity(res); %s %s = static_cast<%s>(curEnv->GetDirectBufferAddress(res)); curEnv->DeleteLocalRef(res); curEnv->DeleteLocalRef(cls); if (curEnv->ExceptionCheck()) { curEnv->ExceptionDescribe() ; } """%(self.getNativeType(), self.temporaryVariableName, self.getNativeType()) return str else: if configGiws().getDisableReturnSize()==True: str+="int lenCol;" str+=strCommon+""" TODO voir si on delete ca char ***arrayOfByteBuffer; arrayOfByteBuffer = new char **[%slenRow]; for (jsize i = 0; i < %slenRow; i++){ /* Line of the array */ jobjectArray resByteBufferLine = reinterpret_cast<jobjectArray>(curEnv->GetObjectArrayElement(res, i)); %slenCol = curEnv->GetArrayLength(resByteBufferLine); arrayOfByteBuffer[i]=new char*[%slenCol]; for (jsize j = 0; j < %slenCol; j++){ jDoubleBuffer resByteBuffer = reinterpret_cast<jDoubleBuffer>(curEnv->GetObjectArrayElement(resByteBufferLine, j)); const char *tempByteBuffer = curEnv->GetByteBufferUTFChars(resByteBuffer, 0); arrayOfByteBuffer[i][j] = new char[strlen(tempByteBuffer) + 1]; strcpy(arrayOfByteBuffer[i][j], tempByteBuffer); curEnv->ReleaseByteBufferUTFChars(resByteBuffer, tempByteBuffer); curEnv->DeleteLocalRef(resByteBuffer); } curEnv->DeleteLocalRef(resByteBufferLine); } """%(strDeclaration, strDeclaration, strDeclaration, strDeclaration, strDeclaration) return str else: if hasattr(self,"parameterName"): str+="""curEnv->DeleteLocalRef(%s);"""%(self.parameterName+"_") return str+""" const char *tempByteBuffer = curEnv->GetByteBufferUTFChars(res, 0); char * %s = new char[strlen(tempByteBuffer) + 1]; strcpy(%s, tempByteBuffer); curEnv->ReleaseByteBufferUTFChars(res, tempByteBuffer); curEnv->DeleteLocalRef(res); """%(self.temporaryVariableName, self.temporaryVariableName)
def __getConstructorWhichInstanciateTheNewObject(self): """ """ # Management of the error when the class cannot be found if configGiws().getThrowsException(): errorMgntClass=""" throw %s::JniClassNotFoundException(curEnv, this->className());"""%(configGiws().getExceptionFileName()) else: errorMgntClass="""std::cerr << "Could not get the Class " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when the global ref could not be created if configGiws().getThrowsException(): errorMgntCreation="""throw %s::JniObjectCreationException(curEnv, this->className());"""%(configGiws().getExceptionFileName()) else: errorMgntCreation="""std::cerr << "Could not create a Global Ref of " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when it is not possible to retrieve the constructor if configGiws().getThrowsException(): errorMgntConstructor="""throw %s::JniObjectCreationException(curEnv, this->className());"""%(configGiws().getExceptionFileName()) else: errorMgntConstructor="""std::cerr << "Could not retrieve the constructor of the class " << this->className() << " with the profile : " << construct << param << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when it is not possible instantiate the obj if configGiws().getThrowsException(): errorMgntInstantiate="""throw %s::JniObjectCreationException(curEnv, this->className());"""%(configGiws().getExceptionFileName()) else: errorMgntInstantiate="""std::cerr << "Could not instantiate the object " << this->className() << " with the constructor : " << construct << param << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" # Management of the error when it is not possible create a global ref if configGiws().getThrowsException(): errorMgntRef="""throw %s::JniObjectCreationException(curEnv, this->className());"""%(configGiws().getExceptionFileName()) else: errorMgntRef="""std::cerr << "Could not create a new global ref of " << this->className() << std::endl; curEnv->ExceptionDescribe(); exit(EXIT_FAILURE);""" ### Init the list of the cache of methodID strMethodID=self.__getDeclarationOfCachingMethodID() constructorProfile="""%s::%s"""%(self.getName(), self.__getConstructorProfileWhichInstanciateTheNewObject()) if self.getExtendedClass()!=None: constructorProfile+=""" : %s(fakeGiwsDataType::fakeGiwsDataType())""" % (self.getExtendedClass().getName()) return """%s { jmethodID constructObject = NULL ; jobject localInstance ; jclass localClass ; const std::string construct="<init>"; const std::string param="()V"; jvm=jvm_; JNIEnv * curEnv = getCurrentEnv(); localClass = curEnv->FindClass( this->className().c_str() ) ; if (localClass == NULL) { %s } this->instanceClass = static_cast<jclass>(curEnv->NewGlobalRef(localClass)); /* localClass is not needed anymore */ curEnv->DeleteLocalRef(localClass); if (this->instanceClass == NULL) { %s } constructObject = curEnv->GetMethodID( this->instanceClass, construct.c_str() , param.c_str() ) ; if(constructObject == NULL){ %s } localInstance = curEnv->NewObject( this->instanceClass, constructObject ) ; if(localInstance == NULL){ %s } this->instance = curEnv->NewGlobalRef(localInstance) ; if(this->instance == NULL){ %s } /* localInstance not needed anymore */ curEnv->DeleteLocalRef(localInstance); /* Methods ID set to NULL */ %s } """%(constructorProfile, errorMgntClass, errorMgntCreation, errorMgntConstructor, errorMgntInstantiate, errorMgntRef, strMethodID)
def specificPostProcessing(self, detachThread): """ Called when we are returning a XXXXXBuffer or an array of XXXBuffer TODO """ # We are doing an exception check here JUST in this case because # in methodGiws::__createMethodBody we usually do it at the end # of the method just after deleting the variable # but when dealing with DoubleBuffer, in this method, we are calling some # methods which override the "exception engine" which drive the JNI # engine crazy. TODO check str = JNIFrameWork().getExceptionCheckProfile(detachThread) if self.isArray(): strCommon = "" strDeclaration = "" if configGiws().getDisableReturnSize() == True: strCommon += "int lenRow;" else: # The size of the array is returned as output argument of the function strDeclaration = "*" self.temporaryVariableName = "byteBufferRes" if self.getDimensionArray() == 1: str += strCommon + """ *lenRow = curEnv->GetDirectBufferCapacity(res); %s %s = static_cast<%s>(curEnv->GetDirectBufferAddress(res)); curEnv->DeleteLocalRef(res); curEnv->DeleteLocalRef(cls); if (curEnv->ExceptionCheck()) { curEnv->ExceptionDescribe() ; } """ % (self.getNativeType(), self.temporaryVariableName, self.getNativeType()) return str else: if configGiws().getDisableReturnSize() == True: str += "int lenCol;" str += strCommon + """ TODO voir si on delete ca char ***arrayOfByteBuffer; arrayOfByteBuffer = new char **[%slenRow]; for (jsize i = 0; i < %slenRow; i++){ /* Line of the array */ jobjectArray resByteBufferLine = reinterpret_cast<jobjectArray>(curEnv->GetObjectArrayElement(res, i)); %slenCol = curEnv->GetArrayLength(resByteBufferLine); arrayOfByteBuffer[i]=new char*[%slenCol]; for (jsize j = 0; j < %slenCol; j++){ jDoubleBuffer resByteBuffer = reinterpret_cast<jDoubleBuffer>(curEnv->GetObjectArrayElement(resByteBufferLine, j)); const char *tempByteBuffer = curEnv->GetByteBufferUTFChars(resByteBuffer, 0); arrayOfByteBuffer[i][j] = new char[strlen(tempByteBuffer) + 1]; strcpy(arrayOfByteBuffer[i][j], tempByteBuffer); curEnv->ReleaseByteBufferUTFChars(resByteBuffer, tempByteBuffer); curEnv->DeleteLocalRef(resByteBuffer); } curEnv->DeleteLocalRef(resByteBufferLine); } """ % (strDeclaration, strDeclaration, strDeclaration, strDeclaration, strDeclaration) return str else: if hasattr(self, "parameterName"): str += """curEnv->DeleteLocalRef(%s);""" % ( self.parameterName + "_") return str + """ const char *tempByteBuffer = curEnv->GetByteBufferUTFChars(res, 0); char * %s = new char[strlen(tempByteBuffer) + 1]; strcpy(%s, tempByteBuffer); curEnv->ReleaseByteBufferUTFChars(res, tempByteBuffer); curEnv->DeleteLocalRef(res); """ % (self.temporaryVariableName, self.temporaryVariableName)
def specificPostProcessing(self, detachThread): """ Preprocessing after calling the java method """ javaType=self.getJavaTypeSyntax() javaTypeNotArray=self.getJavaTypeSyntaxForceNotArray() shortType=self.getJavaShortType(forceNotArray=True) nativeTypeForceNotArray=self.getNativeTypeForceNotArray() if self.isArray(): str="""if (res == NULL) { return NULL; } """ str+=JNIFrameWork().getExceptionCheckProfile(detachThread) strCommon="" strDeclaration="" if configGiws().getDisableReturnSize()==True: strCommon+="int lenRow;" else: # The size of the array is returned as output argument of the function strDeclaration="*" strCommon+=""" %s lenRow = curEnv->GetArrayLength(res); jboolean isCopy = JNI_FALSE; """%(strDeclaration) if self.getDimensionArray() == 1: str+=strCommon+""" /* GetPrimitiveArrayCritical is faster than getXXXArrayElements */ %s *resultsArray = static_cast<%s *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy)); %s myArray= new %s[%s lenRow]; for (jsize i = 0; i < %s lenRow; i++){ myArray[i]=resultsArray[i]; } curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT); curEnv->DeleteLocalRef(res); """%(javaTypeNotArray, javaTypeNotArray, self.getNativeType(), nativeTypeForceNotArray, strDeclaration, strDeclaration) return str else: if configGiws().getDisableReturnSize()==True: str+="int lenCol;" str+=strCommon+""" %s ** myArray = new %s*[%s lenRow]; for(int i=0; i<%s lenRow; i++) { %sArray oneDim = (%sArray)curEnv->GetObjectArrayElement(res, i); %s lenCol=curEnv->GetArrayLength(oneDim); %s *resultsArray = static_cast<%s *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy)); myArray[i] = new %s[%s lenCol]; for(int j=0; j<%s lenCol; j++) { myArray[i][j]= resultsArray[j]; } curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT); } curEnv->DeleteLocalRef(res); """%(self.nativeType, self.nativeType, strDeclaration, strDeclaration, javaTypeNotArray, javaTypeNotArray, strDeclaration, self.nativeType, self.nativeType, nativeTypeForceNotArray, strDeclaration, strDeclaration) return str else: # Not post processing when dealing with primitive types return ""
def specificPreProcessing(self, parameter, detachThread): """ Overrides the preprocessing of the array """ name = parameter.getName() # Management of the error when not enought memory to create the XXXXXBuffer if configGiws().getThrowsException(): errorMgntMem = """%sthrow %s::JniBadAllocException(curEnv);""" % ( detachThread, configGiws().getExceptionFileName()) else: errorMgntMem = """std::cerr << "Could not allocate Java %s array, memory full." << std::endl;%s exit(EXIT_FAILURE);""" % (self.getJavaBufferType(), detachThread) errorMgntMemBis = self.__errorMemoryByteBuffer(detachThread) str = """ jobject buffer%s = curEnv->NewDirectByteBuffer((void*)%s, (jlong)%sSize * sizeof(%s)); if (!buffer%s) { throw GiwsException::JniBadAllocException(curEnv); } if (ByteOrderClass == NULL) { ByteOrderClass = static_cast<jclass>(curEnv->NewGlobalRef(curEnv->FindClass("java/nio/ByteOrder"))); if (ByteOrderClass == NULL) { curEnv->ExceptionDescribe(); } } if (nativeOrderID == NULL) { // public static ByteOrder nativeOrder() nativeOrderID = curEnv->GetStaticMethodID(ByteOrderClass, "nativeOrder", "()Ljava/nio/ByteOrder;"); if (nativeOrderID == NULL) { curEnv->ExceptionDescribe(); } } nativeOrder = curEnv->CallStaticObjectMethod(ByteOrderClass, nativeOrderID, buffer%s); // curEnv->DeleteLocalRef(cls); if (curEnv->ExceptionCheck()) { throw GiwsException::JniCallMethodException(curEnv); } if (bbCls == NULL) { bbCls = static_cast<jclass>(curEnv->NewGlobalRef(curEnv->FindClass("java/nio/ByteBuffer"))); if (bbCls == NULL) { curEnv->ExceptionDescribe(); } } if (orderID == NULL) { orderID = curEnv->GetMethodID(bbCls, "order", "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); if (orderID == NULL) { curEnv->ExceptionDescribe(); } } buffer%s = curEnv->CallObjectMethod(buffer%s, orderID, nativeOrder); """ % (name, name, name, self.nativeType, name, name, name, name) if self.getJavaBufferType() == "ByteBuffer": str = str + """ jobject %s_ = buffer%s; """ % (name, name) return str str = str + """ if (asdbID%s == NULL) { asdbID%s = curEnv->GetMethodID(bbCls, "as%s", "()%s"); if (asdbID%s == NULL) { curEnv->ExceptionDescribe(); } } jobject %s_ = curEnv->CallObjectMethod(buffer%s, asdbID%s); if (%s_ == NULL) { // check that allocation succeed throw GiwsException::JniBadAllocException(curEnv); } """ % (self.getJavaBufferType(), self.getJavaBufferType(), self.getJavaBufferType(), self.getTypeSignature(), self.getJavaBufferType(), name, name, self.getJavaBufferType(), name) return str
def specificPreProcessing(self, parameter, detachThread): """ Overrides the preprocessing of the array """ name=parameter.getName() # Management of the error when not enought memory to create the string if configGiws().getThrowsException(): errorMgntMem="""%sthrow %s::JniBadAllocException(curEnv);"""%(detachThread,configGiws().getExceptionFileName()) else: errorMgntMem="""std::cerr << "Could not allocate Java string array, memory full." << std::endl;%s exit(EXIT_FAILURE);"""%(detachThread) errorMgntMemBis = self.__errorMemoryString(detachThread) if self.isArray(): if self.getDimensionArray() == 1: return """ // create java array of strings. jobjectArray %s_ = curEnv->NewObjectArray( %sSize, stringArrayClass, NULL); if (%s_ == NULL) { %s } // convert each char * to java strings and fill the java array. for ( int i = 0; i < %sSize; i++) { jstring TempString = curEnv->NewStringUTF( %s[i] ); if (TempString == NULL) { %s } curEnv->SetObjectArrayElement( %s_, i, TempString); // avoid keeping reference on too many strings curEnv->DeleteLocalRef(TempString); }"""%(name,name,name,errorMgntMem,name,name,errorMgntMemBis,name) else: return """ // create java array of array of strings. jobjectArray %s_ = curEnv->NewObjectArray( %sSize, curEnv->FindClass("[Ljava/lang/String;"), NULL); if (%s_ == NULL) { %s } for ( int i = 0; i < %sSize; i++) { jobjectArray %sLocal = curEnv->NewObjectArray( %sSizeCol, stringArrayClass, NULL); // convert each char * to java strings and fill the java array. for ( int j = 0; j < %sSizeCol; j++) { jstring TempString = curEnv->NewStringUTF( %s[i][j] ); if (TempString == NULL) { %s } curEnv->SetObjectArrayElement( %sLocal, j, TempString); // avoid keeping reference on too many strings curEnv->DeleteLocalRef(TempString); } curEnv->SetObjectArrayElement(%s_, i, %sLocal); curEnv->DeleteLocalRef(%sLocal); }"""%(name,name,name,errorMgntMem,name,name,name,name,name,errorMgntMemBis,name,name,name,name) else: # Need to store is for the post processing (delete) self.parameterName=name tempName=name+"_" return """ jstring %s = curEnv->NewStringUTF( %s ); if (%s != NULL && %s == NULL) { %s } """%(tempName,name,name,tempName,errorMgntMemBis)
def specificPreProcessing(self, parameter, detachThread): """ Overrides the preprocessing of the array """ name=parameter.getName() # Management of the error when not enought memory to create the XXXXXBuffer if configGiws().getThrowsException(): errorMgntMem="""%sthrow %s::JniBadAllocException(curEnv);"""%(detachThread,configGiws().getExceptionFileName()) else: errorMgntMem="""std::cerr << "Could not allocate Java %s array, memory full." << std::endl;%s exit(EXIT_FAILURE);"""%(self.getJavaBufferType(), detachThread) errorMgntMemBis = self.__errorMemoryByteBuffer(detachThread) str = """ jobject buffer%s = curEnv->NewDirectByteBuffer((void*)%s, (jlong)%sSize * sizeof(%s)); if (!buffer%s) { throw GiwsException::JniBadAllocException(curEnv); } if (ByteOrderClass == NULL) { ByteOrderClass = static_cast<jclass>(curEnv->NewGlobalRef(curEnv->FindClass("java/nio/ByteOrder"))); if (ByteOrderClass == NULL) { curEnv->ExceptionDescribe(); } } if (nativeOrderID == NULL) { // public static ByteOrder nativeOrder() nativeOrderID = curEnv->GetStaticMethodID(ByteOrderClass, "nativeOrder", "()Ljava/nio/ByteOrder;"); if (nativeOrderID == NULL) { curEnv->ExceptionDescribe(); } } nativeOrder = curEnv->CallStaticObjectMethod(ByteOrderClass, nativeOrderID, buffer%s); // curEnv->DeleteLocalRef(cls); if (curEnv->ExceptionCheck()) { throw GiwsException::JniCallMethodException(curEnv); } if (bbCls == NULL) { bbCls = static_cast<jclass>(curEnv->NewGlobalRef(curEnv->FindClass("java/nio/ByteBuffer"))); if (bbCls == NULL) { curEnv->ExceptionDescribe(); } } if (orderID == NULL) { orderID = curEnv->GetMethodID(bbCls, "order", "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); if (orderID == NULL) { curEnv->ExceptionDescribe(); } } buffer%s = curEnv->CallObjectMethod(buffer%s, orderID, nativeOrder); """%(name, name, name, self.nativeType, name, name, name, name) if self.getJavaBufferType() == "ByteBuffer": str=str+""" jobject %s_ = buffer%s; """ % (name, name) return str str=str+""" if (asdbID%s == NULL) { asdbID%s = curEnv->GetMethodID(bbCls, "as%s", "()%s"); if (asdbID%s == NULL) { curEnv->ExceptionDescribe(); } } jobject %s_ = curEnv->CallObjectMethod(buffer%s, asdbID%s); if (%s_ == NULL) { // check that allocation succeed throw GiwsException::JniBadAllocException(curEnv); } """%(self.getJavaBufferType(), self.getJavaBufferType(), self.getJavaBufferType(), self.getTypeSignature(), self.getJavaBufferType(), name, name, self.getJavaBufferType(), name) return str
# The fact that you are presently reading this means that you have had # knowledge of the CeCILL license and that you accept its terms. # # For more information, see the file COPYING from distutils.core import setup from configGiws import configGiws import os root_dir = os.path.dirname(__file__) if root_dir: os.chdir(root_dir) setup (name = "giws", description="Generate C++ class wrappers to call Java methods/objects", version=configGiws().getVersion(), author="Sylvestre Ledru", author_email="*****@*****.**", url="https://github.com/sylvestre/giws/", packages=['.','classRepresentation','datatypes'], scripts=['giws'], license="CeCILL", long_description="""Giws is basically doing the same stuff as SWIG but the opposite. Calling Java from C/C++ can be tricky: JNI calls are complicated especially when dealing with non primivite types or arrays, performance issues must be kept in mind all the time, the code can be redundant (checking exceptions, checking returns of operations...). Giws hides this complexity through a C++ class which wraps the Java class.""" )
def specificPostProcessing(self, detachThread): """ Preprocessing after calling the java method """ javaType = self.getJavaTypeSyntax() javaTypeNotArray = self.getJavaTypeSyntaxForceNotArray() shortType = self.getJavaShortType(forceNotArray=True) nativeTypeForceNotArray = self.getNativeTypeForceNotArray() if self.isArray(): str = """if (res == NULL) { return NULL; } """ str += JNIFrameWork().getExceptionCheckProfile(detachThread) strCommon = "" strDeclaration = "" if configGiws().getDisableReturnSize() == True: strCommon += "int lenRow;" else: # The size of the array is returned as output argument of the function strDeclaration = "*" strCommon += """ %s lenRow = curEnv->GetArrayLength(res); jboolean isCopy = JNI_FALSE; """ % (strDeclaration) if self.getDimensionArray() == 1: str += strCommon + """ /* GetPrimitiveArrayCritical is faster than getXXXArrayElements */ %s *resultsArray = static_cast<%s *>(curEnv->GetPrimitiveArrayCritical(res, &isCopy)); %s myArray= new %s[%s lenRow]; for (jsize i = 0; i < %s lenRow; i++){ myArray[i]=resultsArray[i]; } curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT); curEnv->DeleteLocalRef(res); """ % (javaTypeNotArray, javaTypeNotArray, self.getNativeType( ), nativeTypeForceNotArray, strDeclaration, strDeclaration) return str else: if configGiws().getDisableReturnSize() == True: str += "int lenCol;" str += strCommon + """ %s ** myArray = new %s*[%s lenRow]; for(int i=0; i<%s lenRow; i++) { %sArray oneDim = (%sArray)curEnv->GetObjectArrayElement(res, i); %s lenCol=curEnv->GetArrayLength(oneDim); %s *resultsArray = static_cast<%s *>(curEnv->GetPrimitiveArrayCritical(oneDim, &isCopy)); myArray[i] = new %s[%s lenCol]; for(int j=0; j<%s lenCol; j++) { myArray[i][j]= resultsArray[j]; } curEnv->ReleasePrimitiveArrayCritical(res, resultsArray, JNI_ABORT); } curEnv->DeleteLocalRef(res); """ % (self.nativeType, self.nativeType, strDeclaration, strDeclaration, javaTypeNotArray, javaTypeNotArray, strDeclaration, self.nativeType, self.nativeType, nativeTypeForceNotArray, strDeclaration, strDeclaration) return str else: # Not post processing when dealing with primitive types return ""