001/* 002 * BridJ - Dynamic and blazing-fast native interop for Java. 003 * http://bridj.googlecode.com/ 004 * 005 * Copyright (c) 2010-2013, Olivier Chafik (http://ochafik.com/) 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions are met: 010 * 011 * * Redistributions of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * * Redistributions in binary form must reproduce the above copyright 014 * notice, this list of conditions and the following disclaimer in the 015 * documentation and/or other materials provided with the distribution. 016 * * Neither the name of Olivier Chafik nor the 017 * names of its contributors may be used to endorse or promote products 018 * derived from this software without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY OLIVIER CHAFIK AND CONTRIBUTORS ``AS IS'' AND ANY 021 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 023 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 024 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 027 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 030 */ 031package org.bridj; 032 033import java.lang.annotation.Annotation; 034import static org.bridj.NativeConstants.*; 035import static org.bridj.dyncall.DyncallLibrary.*; 036import org.bridj.ann.Constructor; 037//import org.bridj.cpp.CPPObject; 038 039import java.lang.reflect.*; 040import java.util.ArrayList; 041import java.util.Arrays; 042import java.util.List; 043import java.util.NoSuchElementException; 044import org.bridj.ann.Convention; 045import org.bridj.ann.SetsLastError; 046import org.bridj.ann.DisableDirect; 047import org.bridj.ann.Ptr; 048import org.bridj.ann.Virtual; 049import org.bridj.util.Utils; 050import static org.bridj.util.AnnotationUtils.*; 051 052/** 053 * Internal class that encapsulate all the knowledge about a native method call 054 * : signatures (ASM, dyncall and Java), calling convention, context... 055 * 056 * @author Olivier 057 */ 058public class MethodCallInfo { 059 060 /*public static class GenericMethodInfo { 061 Type returnType, paramsTypes[]; 062 } 063 GenericMethodInfo genericInfo = new GenericMethodInfo();*/ 064 List<CallIO> callIOs; 065 private Class<?> declaringClass; 066 long nativeClass; 067 int returnValueType, paramsValueTypes[]; 068 Method method;//, definition; 069 String methodName, symbolName; 070 private long forwardedPointer; 071 String dcSignature; 072 String javaSignature; 073 String asmSignature; 074 Object javaCallback; 075 boolean isGenericCallback; 076 boolean isObjCBlock; 077 int virtualIndex = -1; 078 int virtualTableOffset = 0; 079 private int dcCallingConvention = DC_CALL_C_DEFAULT; 080 boolean isVarArgs; 081 boolean isStatic; 082 boolean isCPlusPlus; 083 boolean direct; 084 boolean startsWithThis; 085 boolean bNeedsThisPointer; 086 boolean throwsLastError; 087 boolean setsLastError; 088 089 public MethodCallInfo(Method method) { 090 this(method, method); 091 } 092 093 static boolean derivesFrom(Class<?> c, String className) { 094 while (c != null) { 095 if (c.getName().equals(className)) { 096 return true; 097 } 098 c = c.getSuperclass(); 099 } 100 return false; 101 } 102 103 public MethodCallInfo(Type genericReturnType, Type[] parameterTypes, boolean prependJNIPointers) { 104 this(genericReturnType, new Annotation[0], parameterTypes, new Annotation[parameterTypes.length][], prependJNIPointers); 105 } 106 107 public MethodCallInfo(Type genericReturnType, Annotation[] returnAnnotations, Type[] parameterTypes, Annotation[][] paramsAnnotations, boolean prependJNIPointers) { 108 init(null, Utils.getClass(genericReturnType), genericReturnType, returnAnnotations, Utils.getClasses(parameterTypes), parameterTypes, paramsAnnotations, prependJNIPointers, false, true); 109 } 110 111 public MethodCallInfo(Method method, Method definition) { 112 this.setMethod(method); 113 //this.setDefinition(definition); 114 this.setDeclaringClass(method.getDeclaringClass()); 115 symbolName = methodName; 116 117 int modifiers = method.getModifiers(); 118 isStatic = Modifier.isStatic(modifiers); 119 isVarArgs = method.isVarArgs(); 120 boolean isNative = Modifier.isNative(modifiers); 121 boolean isVirtual = isAnnotationPresent(Virtual.class, definition); 122 boolean isDirectModeAllowed = 123 getInheritableAnnotation(DisableDirect.class, definition) == null 124 && BridJ.isDirectModeEnabled(); 125 126 isCPlusPlus = !isStatic && derivesFrom(method.getDeclaringClass(), "org.bridj.cpp.CPPObject"); 127 isObjCBlock = !isStatic && derivesFrom(method.getDeclaringClass(), "org.bridj.objc.ObjCBlock"); 128 129 init( 130 method, 131 method.getReturnType(), method.getGenericReturnType(), method.getAnnotations(), 132 method.getParameterTypes(), method.getGenericParameterTypes(), method.getParameterAnnotations(), 133 isNative, 134 isVirtual, 135 isDirectModeAllowed); 136 137 Convention cc = getInheritableAnnotation(Convention.class, definition); 138 if (cc != null) { 139 setCallingConvention(cc.value()); 140 } 141 List<Class<?>> exceptionTypes = Arrays.asList(definition.getExceptionTypes()); 142 if (!exceptionTypes.isEmpty()) { 143 this.direct = false; // there is no crash / exception protection for direct raw calls 144 if (exceptionTypes.contains(LastError.class)) { 145 this.throwsLastError = true; 146 this.setsLastError = true; 147 } 148 } 149 if (getInheritableAnnotation(SetsLastError.class, definition) != null) { 150 this.direct = false; // there is no crash / exception protection for direct raw calls 151 this.setsLastError = true; 152 } 153 154 } 155 156 protected void init(AnnotatedElement annotatedElement, Class returnType, Type genericReturnType, Annotation[] returnAnnotations, Class[] parameterTypes, Type[] genericParameterTypes, Annotation[][] paramsAnnotations, boolean prependJNIPointers, boolean isVirtual, boolean isDirectModeAllowed) { 157 assert returnType != null; 158 assert genericReturnType != null; 159 assert parameterTypes != null; 160 assert genericParameterTypes != null; 161 assert returnAnnotations != null; 162 assert parameterTypes.length == genericParameterTypes.length; 163 assert paramsAnnotations.length == genericParameterTypes.length; 164 165 int nParams = genericParameterTypes.length; 166 paramsValueTypes = new int[nParams]; 167 168 direct = isDirectModeAllowed; // TODO on native side : test number of parameters (on 64 bits win : must be <= 4) 169 170 StringBuilder javaSig = new StringBuilder(64), 171 asmSig = new StringBuilder(64), 172 dcSig = new StringBuilder(16); 173 javaSig.append('('); 174 asmSig.append('('); 175 if (prependJNIPointers)//!isCPlusPlus) 176 { 177 dcSig.append(DC_SIGCHAR_POINTER).append(DC_SIGCHAR_POINTER); // JNIEnv*, jobject: always present in native-bound functions 178 } 179 if (BridJ.debug) { 180 BridJ.info("Analyzing " + (declaringClass == null ? "anonymous method" : declaringClass.getName() + "." + methodName)); 181 } 182 183 if (isObjCBlock) { 184 appendToSignature(0, ValueType.ePointerValue, Pointer.class, Pointer.class, null, dcSig, null); 185 } 186 187 for (int iParam = 0; iParam < nParams; iParam++) { 188// Options paramOptions = paramsOptions[iParam] = new Options(); 189 Type genericParameterType = genericParameterTypes[iParam]; 190 Class<?> parameterType = parameterTypes[iParam]; 191 192 ValueType paramValueType = getValueType(iParam, nParams, parameterType, genericParameterType, null, paramsAnnotations[iParam]); 193 if (BridJ.veryVerbose) { 194 BridJ.info("\tparam " + paramValueType); 195 } 196 paramsValueTypes[iParam] = paramValueType.ordinal(); 197 198 appendToSignature(iParam, paramValueType, parameterType, genericParameterType, javaSig, dcSig, asmSig); 199 } 200 javaSig.append(')'); 201 asmSig.append(')'); 202 dcSig.append(')'); 203 204 ValueType retType = getValueType(-1, nParams, returnType, genericReturnType, annotatedElement, returnAnnotations); 205 if (BridJ.veryVerbose) { 206 BridJ.info("\treturns " + retType); 207 } 208 appendToSignature(-1, retType, returnType, genericReturnType, javaSig, dcSig, asmSig); 209 returnValueType = retType.ordinal(); 210 211 javaSignature = javaSig.toString(); 212 asmSignature = asmSig.toString(); 213 dcSignature = dcSig.toString(); 214 215 isCPlusPlus = isCPlusPlus || isVirtual; 216 217 if (isCPlusPlus && !isStatic) { 218 if (!startsWithThis) { 219 direct = false; 220 } 221 bNeedsThisPointer = true; 222 if (Platform.isWindows()) { 223 if (!Platform.is64Bits()) { 224 setDcCallingConvention(DC_CALL_C_X86_WIN32_THIS_MS); 225 } 226 } else { 227 //if (!Platform.is64Bits()) 228 // setDcCallingConvention(DC_CALL_C_X86_WIN32_THIS_GNU); 229 } 230 } 231 232 if (nParams > Platform.getMaxDirectMappingArgCount()) { 233 this.direct = false; 234 } 235 236 if (BridJ.veryVerbose) { 237 BridJ.info("\t-> direct " + direct); 238 BridJ.info("\t-> javaSignature " + javaSignature); 239 BridJ.info("\t-> callIOs " + callIOs); 240 BridJ.info("\t-> asmSignature " + asmSignature); 241 BridJ.info("\t-> dcSignature " + dcSignature); 242 } 243 244 if (BridJ.veryVerbose) { 245 BridJ.info((direct ? "[mappable as direct] " : "[not mappable as direct] ") + method); 246 } 247 } 248 boolean hasCC; 249 250 public boolean hasCallingConvention() { 251 return hasCC; 252 } 253 254 public void setCallingConvention(Convention.Style style) { 255 if (style == null) { 256 return; 257 } 258 259 if (!Platform.isWindows() || Platform.is64Bits()) { 260 return; 261 } 262 263 switch (style) { 264 case FastCall: 265 this.direct = false; 266 setDcCallingConvention(Platform.isWindows() ? DC_CALL_C_X86_WIN32_FAST_MS : DC_CALL_C_DEFAULT); // TODO allow GCC-compiled C++ libs on windows 267 break; 268 case Pascal: 269 case StdCall: 270 this.direct = false; 271 setDcCallingConvention(DC_CALL_C_X86_WIN32_STD); 272 break; 273 case ThisCall: 274 this.direct = false; 275 setDcCallingConvention(Platform.isWindows() ? DC_CALL_C_X86_WIN32_THIS_MS : DC_CALL_C_DEFAULT); 276 } 277 if (BridJ.veryVerbose) { 278 BridJ.info("Setting CC " + style + " (-> " + dcCallingConvention + ") for " + methodName); 279 } 280 281 } 282 283 void addCallIO(CallIO handler) { 284 if (callIOs == null) { 285 callIOs = new ArrayList<CallIO>(); 286 } 287 assert handler != null; 288 callIOs.add(handler); 289 } 290 291 public CallIO[] getCallIOs() { 292 if (callIOs == null) { 293 return new CallIO[0]; 294 } 295 return callIOs.toArray(new CallIO[callIOs.size()]); 296 } 297 298 public void prependCallbackCC() { 299 char cc = getDcCallbackConvention(getDcCallingConvention()); 300 if (cc == 0) { 301 return; 302 } 303 304 dcSignature = String.valueOf(DC_SIGCHAR_CC_PREFIX) + String.valueOf(cc) + dcSignature; 305 } 306 307 public String getDcSignature() { 308 return dcSignature; 309 } 310 311 public String getJavaSignature() { 312 return javaSignature; 313 } 314 315 public String getASMSignature() { 316 return asmSignature; 317 } 318 319 boolean getBoolAnnotation(Class<? extends Annotation> ac, AnnotatedElement element, Annotation... directAnnotations) { 320 Annotation ann = getAnnotation(ac, element, directAnnotations); 321 return ann != null; 322 } 323 324 public ValueType getValueType(int iParam, int nParams, Class<?> c, Type t, AnnotatedElement element, Annotation... directAnnotations) { 325 boolean isPtr = isAnnotationPresent(Ptr.class, element, directAnnotations); 326 boolean isCLong = isAnnotationPresent(org.bridj.ann.CLong.class, element, directAnnotations); 327 Constructor cons = getAnnotation(Constructor.class, element, directAnnotations); 328 329 if (isPtr || cons != null || isCLong) { 330 if (!(c == Long.class || c == Long.TYPE)) { 331 throw new RuntimeException("Annotation should only be used on a long parameter, not on a " + c.getName()); 332 } 333 334 if (isPtr) { 335 if (!Platform.is64Bits()) { 336 direct = false; 337 } 338 } else if (isCLong) { 339 if (Platform.CLONG_SIZE != 8) { 340 direct = false; 341 } 342 } else if (cons != null) { 343 isCPlusPlus = true; 344 startsWithThis = true; 345 if (iParam != 0) { 346 throw new RuntimeException("Annotation " + Constructor.class.getName() + " cannot have more than one (long) argument"); 347 } 348 } 349 return isCLong ? ValueType.eCLongValue : ValueType.eSizeTValue; 350 } 351 if (c == null || c.equals(Void.TYPE)) { 352 return ValueType.eVoidValue; 353 } 354 if (c == Integer.class || c == Integer.TYPE) { 355 return ValueType.eIntValue; 356 } 357 if (c == Long.class || c == Long.TYPE) { 358 return !isPtr || Platform.is64Bits() ? ValueType.eLongValue : ValueType.eIntValue; 359 } 360 if (c == Short.class || c == Short.TYPE) { 361 return ValueType.eShortValue; 362 } 363 if (c == Byte.class || c == Byte.TYPE) { 364 return ValueType.eByteValue; 365 } 366 if (c == Boolean.class || c == Boolean.TYPE) { 367 return ValueType.eBooleanValue; 368 } 369 if (c == Float.class || c == Float.TYPE) { 370 usesFloats(); 371 return ValueType.eFloatValue; 372 } 373 if (c == char.class || c == Character.TYPE) { 374 if (Platform.WCHAR_T_SIZE != 2) { 375 direct = false; 376 } 377 return ValueType.eWCharValue; 378 } 379 if (c == Double.class || c == Double.TYPE) { 380 usesFloats(); 381 return ValueType.eDoubleValue; 382 } 383 if (c == CLong.class) { 384 direct = false; 385 return ValueType.eCLongObjectValue; 386 } 387 if (c == SizeT.class) { 388 direct = false; 389 return ValueType.eSizeTObjectValue; 390 } 391 if (c == TimeT.class) { 392 direct = false; 393 return ValueType.eTimeTObjectValue; 394 } 395 if (Pointer.class.isAssignableFrom(c)) { 396 direct = false; 397 CallIO cio = CallIO.Utils.createPointerCallIO(c, t); 398 if (BridJ.veryVerbose) { 399 BridJ.info("CallIO : " + cio); 400 } 401 addCallIO(cio); 402 return ValueType.ePointerValue; 403 } 404 if (c.isArray() && iParam == nParams - 1) { 405 direct = false; 406 return ValueType.eEllipsis; 407 } 408 if (ValuedEnum.class.isAssignableFrom(c)) { 409 direct = false; 410 CallIO cio = CallIO.Utils.createValuedEnumCallIO((Class) Utils.getClass(Utils.getUniqueParameterizedTypeParameter(t))); 411 if (BridJ.veryVerbose) { 412 BridJ.info("CallIO : " + cio); 413 } 414 addCallIO(cio); 415 416 return ValueType.eIntFlagSet; 417 } 418 if (NativeObject.class.isAssignableFrom(c)) { 419 Pointer<DCstruct> pStruct = null; 420 if (StructObject.class.isAssignableFrom(c)) { 421 StructIO io = StructIO.getInstance(c, t); 422 try { 423 pStruct = DyncallStructs.buildDCstruct(io.desc); 424 } catch (Throwable th) { 425 BridJ.error("Unable to create low-level struct metadata for " + Utils.toString(t) + " : won't be able to use it as a by-value function argument.", th); 426 } 427 } 428 addCallIO(new CallIO.NativeObjectHandler((Class<? extends NativeObject>) c, t, pStruct)); 429 direct = false; 430 return ValueType.eNativeObjectValue; 431 } 432 433 throw new NoSuchElementException("No " + ValueType.class.getSimpleName() + " for class " + c.getName()); 434 } 435 436 void usesFloats() { 437 /* 438 if (direct && Platform.isMacOSX()) { 439 direct = false; 440 assert BridJ.warning("[unstable direct] FIXME Disable direct call due to float/double usage in " + method); 441 } 442 */ 443 } 444 445 public void appendToSignature(int iParam, ValueType type, Class<?> parameterType, Type genericParameterType, StringBuilder javaSig, StringBuilder dcSig, StringBuilder asmSig) { 446 char dcChar; 447 String javaChar, asmChar = null; 448 switch (type) { 449 case eVoidValue: 450 dcChar = DC_SIGCHAR_VOID; 451 javaChar = "V"; 452 break; 453 case eIntValue: 454 dcChar = DC_SIGCHAR_INT; 455 javaChar = "I"; 456 break; 457 case eLongValue: 458 dcChar = DC_SIGCHAR_LONGLONG; 459 javaChar = "J"; 460 break; 461 case eCLongValue: 462 javaChar = "J"; 463 dcChar = DC_SIGCHAR_LONG; 464 if (Platform.CLONG_SIZE != 8) { 465 direct = false; 466 } 467 break; 468 case eSizeTValue: 469 javaChar = "J"; 470 if (Platform.SIZE_T_SIZE == 8) { 471 dcChar = DC_SIGCHAR_LONGLONG; 472 } else { 473 dcChar = DC_SIGCHAR_INT; 474 direct = false; 475 } 476 break; 477 case eShortValue: 478 dcChar = DC_SIGCHAR_SHORT; 479 javaChar = "S"; 480 break; 481 case eDoubleValue: 482 dcChar = DC_SIGCHAR_DOUBLE; 483 javaChar = "D"; 484 break; 485 case eFloatValue: 486 dcChar = DC_SIGCHAR_FLOAT; 487 javaChar = "F"; 488 break; 489 case eByteValue: 490 dcChar = DC_SIGCHAR_CHAR; 491 javaChar = "B"; 492 break; 493 case eBooleanValue: 494 dcChar = DC_SIGCHAR_BOOL; 495 javaChar = "Z"; 496 break; 497 case eWCharValue: 498 switch (Platform.WCHAR_T_SIZE) { 499 case 1: 500 dcChar = DC_SIGCHAR_CHAR; 501 direct = false; 502 break; 503 case 2: 504 dcChar = DC_SIGCHAR_SHORT; 505 break; 506 case 4: 507 dcChar = DC_SIGCHAR_INT; 508 direct = false; 509 break; 510 default: 511 throw new RuntimeException("Unhandled sizeof(wchar_t) in GetJavaTypeSignature: " + Platform.WCHAR_T_SIZE); 512 } 513 javaChar = "C"; 514 break; 515 case eIntFlagSet: 516 dcChar = DC_SIGCHAR_INT; 517 javaChar = "L" + parameterType.getName().replace('.', '/') + ";";//"Lorg/bridj/ValuedEnum;"; 518 direct = false; 519 break; 520 case eCLongObjectValue: 521 dcChar = DC_SIGCHAR_POINTER; 522 javaChar = "Lorg/bridj/CLong;"; 523 direct = false; 524 break; 525 case eSizeTObjectValue: 526 dcChar = DC_SIGCHAR_POINTER; 527 javaChar = "Lorg/bridj/SizeT;"; 528 direct = false; 529 break; 530 case eTimeTObjectValue: 531 dcChar = DC_SIGCHAR_POINTER; 532 javaChar = "Lorg/bridj/TimeT;"; 533 direct = false; 534 break; 535 case ePointerValue: 536 dcChar = DC_SIGCHAR_POINTER; 537 javaChar = "L" + parameterType.getName().replace('.', '/') + ";"; 538// javaChar = "Lorg/bridj/Pointer;"; 539 direct = false; 540 break; 541 case eNativeObjectValue: 542 dcChar = DC_SIGCHAR_STRUCT; // TODO : unroll struct signature ? 543 javaChar = "L" + parameterType.getName().replace('.', '/') + ";"; 544 direct = false; 545// if (parameterType.equals(declaringClass)) { 546// // special case of self-returning pointers 547// dcChar = DC_SIGCHAR_POINTER; 548 break; 549 case eEllipsis: 550 javaChar = "[Ljava/lang/Object;"; 551 dcChar = '?'; 552 break; 553 default: 554 direct = false; 555 throw new RuntimeException("Unhandled " + ValueType.class.getSimpleName() + ": " + type); 556 } 557 if (genericParameterType instanceof ParameterizedType && iParam < 0) { 558 ParameterizedType pt = (ParameterizedType) genericParameterType; 559 // TODO handle all cases !!! 560 Type[] ts = pt.getActualTypeArguments(); 561 if (ts != null && ts.length == 1) { 562 Type t = ts[0]; 563 if (t instanceof ParameterizedType) { 564 t = ((ParameterizedType) t).getRawType(); 565 } 566 if (t instanceof Class) { 567 Class c = (Class) t; 568 if (javaChar.endsWith(";")) { 569 asmChar = javaChar.substring(0, javaChar.length() - 1) + "<*L" + c.getName().replace('.', '/') + ";>"; 570 //asmChar += ";"; 571 } 572 } 573 } 574 } 575 if (javaSig != null) { 576 javaSig.append(javaChar); 577 } 578 if (asmChar == null) { 579 asmChar = javaChar; 580 } 581 if (asmSig != null) { 582 asmSig.append(asmChar); 583 } 584 if (dcSig != null) { 585 dcSig.append(dcChar); 586 } 587 } 588 /* 589 public void setDefinition(Method definition) { 590 this.definition = definition; 591 } 592 593 public Method getDefinition() { 594 return definition; 595 } 596 */ 597 598 public void setMethod(Method method) { 599 this.method = method; 600 if (method != null) { 601 this.methodName = method.getName(); 602 } 603 if (declaringClass == null) { 604 setDeclaringClass(method.getDeclaringClass()); 605 } 606 607 } 608 609 public void setJavaSignature(String javaSignature) { 610 this.javaSignature = javaSignature; 611 } 612 613 public Method getMethod() { 614 return method; 615 } 616 617 public void setDeclaringClass(Class<?> declaringClass) { 618 this.declaringClass = declaringClass; 619 } 620 621 public Class<?> getDeclaringClass() { 622 return declaringClass; 623 } 624 625 public void setForwardedPointer(long forwardedPointer) { 626 this.forwardedPointer = forwardedPointer; 627 } 628 629 public long getForwardedPointer() { 630 return forwardedPointer; 631 } 632 633 /** 634 * Used for C++ virtual indexes and for struct fields ids 635 * 636 * @param virtualIndex 637 */ 638 public void setVirtualIndex(int virtualIndex) { 639 //new RuntimeException("Setting virtualIndex of " + getMethod().getName() + " = " + virtualIndex).printStackTrace(); 640 this.virtualIndex = virtualIndex; 641 642 if (BridJ.veryVerbose) { 643 BridJ.info("\t-> virtualIndex " + virtualIndex); 644 } 645 } 646 647 public int getVirtualIndex() { 648 return virtualIndex; 649 } 650 651 public String getSymbolName() { 652 return symbolName; 653 } 654 655 public void setSymbolName(String symbolName) { 656 this.symbolName = symbolName; 657 } 658 659 static char getDcCallbackConvention(int dcCallingConvention) { 660 switch (dcCallingConvention) { 661 case DC_CALL_C_X86_WIN32_STD: 662 return DC_SIGCHAR_CC_STDCALL; 663 case DC_CALL_C_X86_WIN32_FAST_MS: 664 return DC_SIGCHAR_CC_FASTCALL_MS; 665 case DC_CALL_C_X86_WIN32_FAST_GNU: 666 return DC_SIGCHAR_CC_FASTCALL_GNU; 667 case DC_CALL_C_X86_WIN32_THIS_MS: 668 return DC_SIGCHAR_CC_THISCALL_MS; 669 default: 670 return 0; 671 } 672 } 673 674 public void setDcCallingConvention(int dcCallingConvention) { 675 hasCC = true; 676 this.dcCallingConvention = dcCallingConvention; 677 } 678 679 public int getDcCallingConvention() { 680 return dcCallingConvention; 681 } 682 683 public Object getJavaCallback() { 684 return javaCallback; 685 } 686 687 public void setJavaCallback(Object javaCallback) { 688 this.javaCallback = javaCallback; 689 } 690 691 public void setGenericCallback(boolean genericCallback) { 692 this.isGenericCallback = genericCallback; 693 } 694 695 public boolean isGenericCallback() { 696 return isGenericCallback; 697 } 698 699 public void setNativeClass(long nativeClass) { 700 this.nativeClass = nativeClass; 701 } 702}