diff options
-rwxr-xr-x | make/dynlink-unix-CustomJavaCode.java | 2 | ||||
-rwxr-xr-x | make/dynlink-windows-CustomJavaCode.java | 4 | ||||
-rwxr-xr-x | make/dynlink-windows.cfg | 21 | ||||
-rwxr-xr-x | make/stub_includes/windows/dynamic-linker.h | 5 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/CMethodBindingEmitter.java | 176 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaConfiguration.java | 11 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaEmitter.java | 24 | ||||
-rwxr-xr-x | src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java | 3 | ||||
-rwxr-xr-x | src/java/com/sun/gluegen/runtime/WindowsDynamicLinkerImpl.java | 14 | ||||
-rwxr-xr-x | src/native/windows/WindowsDynamicLinkerImpl_JNI.c | 53 |
10 files changed, 204 insertions, 109 deletions
diff --git a/make/dynlink-unix-CustomJavaCode.java b/make/dynlink-unix-CustomJavaCode.java index 36a1603..5d10edf 100755 --- a/make/dynlink-unix-CustomJavaCode.java +++ b/make/dynlink-unix-CustomJavaCode.java @@ -6,7 +6,7 @@ public long openLibrary(String pathname) { // other words, one can actually link against the library instead of // having to dlsym all entry points. System.loadLibrary() uses // RTLD_LOCAL visibility so can't be used for this purpose. - return dlopen(pathname, RTLD_GLOBAL); + return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL); } public long lookupSymbol(long libraryHandle, String symbolName) { diff --git a/make/dynlink-windows-CustomJavaCode.java b/make/dynlink-windows-CustomJavaCode.java index 986ec81..4101f4c 100755 --- a/make/dynlink-windows-CustomJavaCode.java +++ b/make/dynlink-windows-CustomJavaCode.java @@ -1,9 +1,9 @@ public long openLibrary(String libraryName) { - return LoadLibraryA(libraryName); + return LoadLibraryW(libraryName); } public long lookupSymbol(long libraryHandle, String symbolName) { - return GetProcAddress(libraryHandle, symbolName); + return GetProcAddressA(libraryHandle, symbolName); } public void closeLibrary(long libraryHandle) { diff --git a/make/dynlink-windows.cfg b/make/dynlink-windows.cfg index 871326e..fe69e1c 100755 --- a/make/dynlink-windows.cfg +++ b/make/dynlink-windows.cfg @@ -8,18 +8,23 @@ HierarchicalNativeOutput false IncludeAs CustomJavaCode WindowsDynamicLinkerImpl dynlink-windows-CustomJavaCode.java CustomCCode #include <windows.h> -CustomCCode /* This typedef is only needed for VC6 */ -CustomCCode #if _MSC_VER <= 1200 +CustomCCode /* This typedef is apparently needed for compilers before VC8, +CustomCCode and for the embedded ARM compilers we're using */ +CustomCCode #if (_MSC_VER < 1400) || defined(UNDER_CE) CustomCCode typedef int intptr_t; CustomCCode #endif +CustomCCode /* GetProcAddress doesn't exist in A/W variants under desktop Windows */ +CustomCCode #ifndef UNDER_CE +CustomCCode #define GetProcAddressA GetProcAddress +CustomCCode #endif -ArgumentIsString LoadLibraryA 0 -ArgumentIsString GetProcAddress 1 +ArgumentIsString LoadLibraryW 0 +ArgumentIsString GetProcAddressA 1 Opaque long HANDLE Opaque long PROC # Hide the platform-specific functions -AccessControl GetLastError PRIVATE -AccessControl LoadLibraryA PRIVATE -AccessControl GetProcAddress PRIVATE -AccessControl FreeLibrary PRIVATE +AccessControl GetLastError PRIVATE +AccessControl LoadLibraryW PRIVATE +AccessControl GetProcAddressA PRIVATE +AccessControl FreeLibrary PRIVATE diff --git a/make/stub_includes/windows/dynamic-linker.h b/make/stub_includes/windows/dynamic-linker.h index e8a8bd5..1b06902 100755 --- a/make/stub_includes/windows/dynamic-linker.h +++ b/make/stub_includes/windows/dynamic-linker.h @@ -17,6 +17,7 @@ typedef struct _handle* HANDLE; typedef HANDLE HMODULE; typedef long LONG; typedef const char* LPCSTR; +typedef const short* LPCWSTR; typedef void* LPVOID; typedef struct _proc* PROC; typedef unsigned int* PUINT; @@ -26,6 +27,6 @@ typedef unsigned short WORD; // Dynamic loading routines WINBASEAPI DWORD WINAPI GetLastError(VOID); -WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName); -WINBASEAPI PROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName); +WINBASEAPI HMODULE WINAPI LoadLibraryW(LPCWSTR lpLibFileName); +WINBASEAPI PROC WINAPI GetProcAddressA(HMODULE hModule, LPCSTR lpProcName); WINBASEAPI BOOL WINAPI FreeLibrary(HMODULE hLibModule); diff --git a/src/java/com/sun/gluegen/CMethodBindingEmitter.java b/src/java/com/sun/gluegen/CMethodBindingEmitter.java index 93a625f..446e5ca 100644 --- a/src/java/com/sun/gluegen/CMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/CMethodBindingEmitter.java @@ -113,6 +113,11 @@ public class CMethodBindingEmitter extends FunctionEmitter // warnings are incorrect. private static final boolean EMIT_NULL_CHECKS = true; + protected static final String STRING_CHARS_PREFIX = "_strchars_"; + + // We need this in order to compute sizes of certain types + protected MachineDescription machDesc; + /** * Constructs an emitter for the specified binding, and sets a default * comment emitter that will emit the signature of the C function that is @@ -125,7 +130,8 @@ public class CMethodBindingEmitter extends FunctionEmitter boolean isOverloadedBinding, boolean isJavaMethodStatic, boolean forImplementingMethodCall, - boolean forIndirectBufferAndArrayImplementation) + boolean forIndirectBufferAndArrayImplementation, + MachineDescription machDesc) { super(output); @@ -141,6 +147,7 @@ public class CMethodBindingEmitter extends FunctionEmitter this.forImplementingMethodCall = forImplementingMethodCall; this.forIndirectBufferAndArrayImplementation = forIndirectBufferAndArrayImplementation; + this.machDesc = machDesc; setCommentEmitter(defaultCommentEmitter); } @@ -291,6 +298,12 @@ public class CMethodBindingEmitter extends FunctionEmitter */ public final boolean forIndirectBufferAndArrayImplementation() { return forIndirectBufferAndArrayImplementation; } + /** + * Used for certain internal type size computations + */ + public final MachineDescription getMachineDescription() { return machDesc; } + + protected void emitReturnType(PrintWriter writer) { writer.print("JNIEXPORT "); @@ -437,7 +450,13 @@ public class CMethodBindingEmitter extends FunctionEmitter emittedDataCopyTemps = true; } } else if (type.isString()) { - writer.print(" const char* _UTF8"); + Type cType = binding.getCArgumentType(i); + if (isUTF8Type(cType)) { + writer.print(" const char* "); + } else { + writer.print(" jchar* "); + } + writer.print(STRING_CHARS_PREFIX); writer.print(binding.getArgumentName(i)); writer.println(" = NULL;"); } @@ -500,6 +519,33 @@ public class CMethodBindingEmitter extends FunctionEmitter } } + /** Checks a type to see whether it is for a UTF-8 pointer type + (i.e., "const char *", "const char **"). False implies that this + type is for a Unicode pointer type ("jchar *", "jchar **"). */ + protected boolean isUTF8Type(Type type) { + int i = 0; + // Try to dereference the type at most two levels + while (!type.isInt() && (i < 2)) { + PointerType pt = type.asPointer(); + if (pt != null) { + type = pt.getTargetType(); + } else { + ArrayType arrt = type.asArray(); + if (arrt == null) { + throw new IllegalArgumentException("Type " + type + " should have been a pointer or array type"); + } + type = arrt.getElementType(); + } + } + if (!type.isInt()) { + throw new IllegalArgumentException("Type " + type + " should have been a one- or two-dimensional integer pointer or array type"); + } + if (type.getSize(machDesc) != 1 && type.getSize(machDesc) != 2) { + throw new IllegalArgumentException("Type " + type + " should have been a one- or two-dimensional pointer to char or short"); + } + return (type.getSize(machDesc) == 1); + } + /** Checks a type (expected to be pointer-to-pointer) for const-ness */ protected boolean isConstPtrPtr(Type type) { if (type.pointerDepth() != 2) { @@ -672,10 +718,11 @@ public class CMethodBindingEmitter extends FunctionEmitter if (javaArgType.isStringArray()) { writer.print(" "); - emitGetStringUTFChars(writer, - "(jstring) _tmpObj", - convName+"_copy[_copyIndex]", - true); + emitGetStringChars(writer, + "(jstring) _tmpObj", + convName+"_copy[_copyIndex]", + isUTF8Type(cArgType), + true); } else if (javaArgType.isNIOBufferArray()) { /* We always assume an integer "byte offset" argument follows any Buffer in the method binding. */ @@ -735,20 +782,11 @@ public class CMethodBindingEmitter extends FunctionEmitter continue; } - if (EMIT_NULL_CHECKS) { - writer.print(" if ("); - writer.print(binding.getArgumentName(i)); - writer.println(" != NULL) {"); - } - - emitGetStringUTFChars(writer, - binding.getArgumentName(i), - "_UTF8" + binding.getArgumentName(i), - false); - - if (EMIT_NULL_CHECKS) { - writer.println(" }"); - } + emitGetStringChars(writer, + binding.getArgumentName(i), + STRING_CHARS_PREFIX + binding.getArgumentName(i), + isUTF8Type(binding.getCArgumentType(i)), + false); } } } @@ -767,6 +805,7 @@ public class CMethodBindingEmitter extends FunctionEmitter if (javaArgType.isJNIEnv() || binding.isArgumentThisPointer(i)) { continue; } + Type cArgType = binding.getCArgumentType(i); if (javaArgType.isArray() || (javaArgType.isNIOBuffer() && forIndirectBufferAndArrayImplementation) || @@ -800,9 +839,6 @@ public class CMethodBindingEmitter extends FunctionEmitter // // FIXME: should factor out this whole block of code into a separate // method for clarity and maintenance purposes - Type cArgType = binding.getCArgumentType(i); - String cArgTypeName = cArgType.getName(); - if (!isConstPtrPtr(cArgType)) { // FIXME: handle any cleanup from treatment of non-const args, // assuming they were treated differently in @@ -902,11 +938,15 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.println(" != NULL) {"); } - writer.print(" (*env)->ReleaseStringUTFChars(env, "); - writer.print(binding.getArgumentName(i)); - writer.print(", _UTF8"); - writer.print(binding.getArgumentName(i)); - writer.println(");"); + if (isUTF8Type(cArgType)) { + writer.print(" (*env)->ReleaseStringUTFChars(env, "); + writer.print(binding.getArgumentName(i)); + writer.print(", " + STRING_CHARS_PREFIX); + writer.print(binding.getArgumentName(i)); + writer.println(");"); + } else { + writer.println(" free((void*) " + STRING_CHARS_PREFIX + binding.getArgumentName(i) + ");"); + } if (EMIT_NULL_CHECKS) { writer.println(" }"); @@ -950,7 +990,7 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.print("_copy"); } } else { - if (javaArgType.isString()) { writer.print("_UTF8"); } + if (javaArgType.isString()) { writer.print(STRING_CHARS_PREFIX); } writer.print(binding.getArgumentName(i)); } } @@ -1249,44 +1289,82 @@ public class CMethodBindingEmitter extends FunctionEmitter } } - private void emitGetStringUTFChars(PrintWriter writer, - String sourceVarName, - String receivingVarName, - boolean emitElseClause) + private void emitCalloc(PrintWriter writer, + String targetVarName, + String elementTypeString, + String numElementsExpression, + String mallocFailureErrorString) { + writer.print(" "); + writer.print(targetVarName); + writer.print(" = ("); + writer.print(elementTypeString); + writer.print(" *) calloc("); + writer.print(numElementsExpression); + writer.print(", sizeof("); + writer.print(elementTypeString); + writer.println("));"); + // Catch memory allocation failure if (EMIT_NULL_CHECKS) { - writer.print(" if ("); + emitOutOfMemoryCheck( + writer, targetVarName, + mallocFailureErrorString); + } + } + + private void emitGetStringChars(PrintWriter writer, + String sourceVarName, + String receivingVarName, + boolean isUTF8, + boolean emitElseClause) + { + if (EMIT_NULL_CHECKS) { + writer.print(" if ("); writer.print(sourceVarName); writer.println(" != NULL) {"); } - writer.print(" "); - writer.print(receivingVarName); - writer.print(" = (*env)->GetStringUTFChars(env, "); - writer.print(sourceVarName); - writer.println(", (jboolean*)NULL);"); - // Catch memory allocation failure in the event that the VM didn't pin - // the String and failed to allocate a copy - if (EMIT_NULL_CHECKS) { - emitOutOfMemoryCheck( - writer, receivingVarName, - "Failed to get UTF-8 chars for argument \\\""+sourceVarName+"\\\""); + if (isUTF8) { + writer.print(" "); + writer.print(receivingVarName); + writer.print(" = (*env)->GetStringUTFChars(env, "); + writer.print(sourceVarName); + writer.println(", (jboolean*)NULL);"); + // Catch memory allocation failure in the event that the VM didn't pin + // the String and failed to allocate a copy + if (EMIT_NULL_CHECKS) { + emitOutOfMemoryCheck( + writer, receivingVarName, + "Failed to get UTF-8 chars for argument \\\""+sourceVarName+"\\\""); + } + } else { + // The UTF-16 case is basically Windows specific. Unix platforms + // tend to use only the UTF-8 encoding. On Windows the problem + // is that wide character strings are expected to be null + // terminated, but the JNI GetStringChars doesn't return a + // null-terminated Unicode string. For this reason we explicitly + // calloc our buffer, including the null terminator, and use + // GetStringRegion to fetch the string's characters. + emitCalloc(writer, + receivingVarName, + "jchar", + "(*env)->GetStringLength(env, " + sourceVarName + ") + 1", + "Could not allocate temporary buffer for copying string argument \\\""+sourceVarName+"\\\""); + writer.println(" (*env)->GetStringRegion(env, " + sourceVarName + ", 0, (*env)->GetStringLength(env, " + sourceVarName + "), " + receivingVarName + ");"); } if (EMIT_NULL_CHECKS) { - writer.print(" }"); + writer.print(" }"); if (emitElseClause) { writer.print(" else {"); writer.print(" "); writer.print(receivingVarName); writer.println(" = NULL;"); - writer.println(" }"); + writer.println(" }"); } else { writer.println(); } } } - - private void emitGetDirectBufferAddress(PrintWriter writer, String sourceVarName, String receivingVarTypeString, diff --git a/src/java/com/sun/gluegen/JavaConfiguration.java b/src/java/com/sun/gluegen/JavaConfiguration.java index 7f6efa9..a452183 100644 --- a/src/java/com/sun/gluegen/JavaConfiguration.java +++ b/src/java/com/sun/gluegen/JavaConfiguration.java @@ -105,7 +105,7 @@ public class JavaConfiguration { private Set/*<String>*/ returnsString = new HashSet(); private Map/*<String, String>*/ returnedArrayLengths = new HashMap(); /** - * Key is function that has some byte[] arguments that should be + * Key is function that has some byte[] or short[] arguments that should be * converted to String args; value is List of Integer argument indices */ private Map/*<String,List<Integer>>*/ argumentsAreString = new HashMap(); @@ -1065,8 +1065,8 @@ public class JavaConfiguration { * </pre> * */ - protected void readArgumentIsString(StringTokenizer tok, String filename, int lineNo) { - try { + protected void readArgumentIsString(StringTokenizer tok, String filename, int lineNo) { + try { String methodName = tok.nextToken(); ArrayList argIndices = new ArrayList(2); while (tok.hasMoreTokens()) { @@ -1074,10 +1074,9 @@ public class JavaConfiguration { argIndices.add(idx); } - if(argIndices.size() > 0) { + if (argIndices.size() > 0) { argumentsAreString.put(methodName, argIndices); - } - else { + } else { throw new RuntimeException("ERROR: Error parsing \"ArgumentIsString\" command at line " + lineNo + " in file \"" + filename + "\": directive requires specification of at least 1 index"); } diff --git a/src/java/com/sun/gluegen/JavaEmitter.java b/src/java/com/sun/gluegen/JavaEmitter.java index 6b51ef0..ef5c36d 100644 --- a/src/java/com/sun/gluegen/JavaEmitter.java +++ b/src/java/com/sun/gluegen/JavaEmitter.java @@ -508,7 +508,8 @@ public class JavaEmitter implements GlueEmitter { true, /* NOTE: we always disambiguate with a suffix now, so this is optional */ cfg.allStatic(), (binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue), - false); + false, + machDesc64); if (returnValueCapacityFormat != null) { cEmitter.setReturnValueCapacityExpression(returnValueCapacityFormat); } @@ -532,7 +533,8 @@ public class JavaEmitter implements GlueEmitter { true, /* NOTE: we always disambiguate with a suffix now, so this is optional */ cfg.allStatic(), binding.needsNIOWrappingOrUnwrapping(), - true); + true, + machDesc64); if (returnValueCapacityFormat != null) { cEmitter.setReturnValueCapacityExpression(returnValueCapacityFormat); } @@ -898,7 +900,8 @@ public class JavaEmitter implements GlueEmitter { true, // FIXME: this is optional at this point false, true, - false); // FIXME: should unify this with the general emission code + false, // FIXME: should unify this with the general emission code + machDesc64); cEmitter.emit(); } catch (Exception e) { System.err.println("While processing field " + field + " of type " + name + ":"); @@ -1520,7 +1523,7 @@ public class JavaEmitter implements GlueEmitter { } // List of the indices of the arguments in this function that should be - // converted from byte[] to String + // converted from byte[] or short[] to String List stringArgIndices = cfg.stringArguments(binding.getName()); for (int i = 0; i < sym.getNumArguments(); i++) { @@ -1534,9 +1537,14 @@ public class JavaEmitter implements GlueEmitter { //System.out.println("Forcing conversion of " + binding.getName() + " arg #" + i + " from byte[] to String "); if (mappedType.isCVoidPointerType() || mappedType.isCCharPointerType() || - (mappedType.isArray() && mappedType.getJavaClass() == ArrayTypes.byteBufferArrayClass)) { - // convert mapped type from void* and byte[] to String, or ByteBuffer[] to String[] - if (mappedType.getJavaClass() == ArrayTypes.byteBufferArrayClass) { + mappedType.isCShortPointerType() || + (mappedType.isArray() && + (mappedType.getJavaClass() == ArrayTypes.byteBufferArrayClass) || + (mappedType.getJavaClass() == ArrayTypes.shortBufferArrayClass))) { + // convert mapped type from: + // void*, byte[], and short[] to String + // ByteBuffer[] and ShortBuffer[] to String[] + if (mappedType.isArray()) { mappedType = javaType(ArrayTypes.stringArrayClass); } else { mappedType = javaType(String.class); @@ -1546,7 +1554,7 @@ public class JavaEmitter implements GlueEmitter { throw new RuntimeException( "Cannot apply ArgumentIsString configuration directive to " + "argument " + i + " of \"" + sym + "\": argument type is not " + - "a \"void*\", \"char *\", or \"char**\" equivalent"); + "a \"void*\", \"char *\", \"short *\", \"char**\", or \"short**\" equivalent"); } } binding.addJavaArgumentType(mappedType); diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java index 84e8132..41bae10 100755 --- a/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java @@ -79,7 +79,8 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { methodToWrap.getIsOverloadedBinding(), methodToWrap.getIsJavaMethodStatic(), true, - methodToWrap.forIndirectBufferAndArrayImplementation() + methodToWrap.forIndirectBufferAndArrayImplementation(), + methodToWrap.getMachineDescription() ); if (methodToWrap.getReturnValueCapacityExpression() != null) { diff --git a/src/java/com/sun/gluegen/runtime/WindowsDynamicLinkerImpl.java b/src/java/com/sun/gluegen/runtime/WindowsDynamicLinkerImpl.java index c1d2fa0..553c2f2 100755 --- a/src/java/com/sun/gluegen/runtime/WindowsDynamicLinkerImpl.java +++ b/src/java/com/sun/gluegen/runtime/WindowsDynamicLinkerImpl.java @@ -1,4 +1,4 @@ -/* !---- DO NOT EDIT: This file autogenerated by com\sun\gluegen\JavaEmitter.java on Mon Jul 31 16:26:59 PDT 2006 ----! */ +/* !---- DO NOT EDIT: This file autogenerated by com\sun\gluegen\JavaEmitter.java on Tue May 27 02:37:55 PDT 2008 ----! */ package com.sun.gluegen.runtime; @@ -14,20 +14,20 @@ public class WindowsDynamicLinkerImpl implements DynamicLinker /** Interface to C language function: <br> <code> DWORD GetLastError(void); </code> */ private static native int GetLastError(); - /** Interface to C language function: <br> <code> PROC GetProcAddress(HANDLE hModule, LPCSTR lpProcName); </code> */ - private static native long GetProcAddress(long hModule, java.lang.String lpProcName); + /** Interface to C language function: <br> <code> PROC GetProcAddressA(HANDLE hModule, LPCSTR lpProcName); </code> */ + private static native long GetProcAddressA(long hModule, java.lang.String lpProcName); - /** Interface to C language function: <br> <code> HANDLE LoadLibraryA(LPCSTR lpLibFileName); </code> */ - private static native long LoadLibraryA(java.lang.String lpLibFileName); + /** Interface to C language function: <br> <code> HANDLE LoadLibraryW(LPCWSTR lpLibFileName); </code> */ + private static native long LoadLibraryW(java.lang.String lpLibFileName); // --- Begin CustomJavaCode .cfg declarations public long openLibrary(String libraryName) { - return LoadLibraryA(libraryName); + return LoadLibraryW(libraryName); } public long lookupSymbol(long libraryHandle, String symbolName) { - return GetProcAddress(libraryHandle, symbolName); + return GetProcAddressA(libraryHandle, symbolName); } public void closeLibrary(long libraryHandle) { diff --git a/src/native/windows/WindowsDynamicLinkerImpl_JNI.c b/src/native/windows/WindowsDynamicLinkerImpl_JNI.c index db20b15..63afd99 100755 --- a/src/native/windows/WindowsDynamicLinkerImpl_JNI.c +++ b/src/native/windows/WindowsDynamicLinkerImpl_JNI.c @@ -1,14 +1,20 @@ -/* !---- DO NOT EDIT: This file autogenerated by com\sun\gluegen\JavaEmitter.java on Mon Jul 31 16:26:59 PDT 2006 ----! */ +/* !---- DO NOT EDIT: This file autogenerated by com\sun\gluegen\JavaEmitter.java on Tue May 27 02:37:55 PDT 2008 ----! */ #include <jni.h> +#include <stdlib.h> #include <assert.h> #include <windows.h> - /* This typedef is apparently needed for compilers before VC8 */ - #if _MSC_VER < 1400 + /* This typedef is apparently needed for compilers before VC8, + and for the embedded ARM compilers we're using */ + #if (_MSC_VER < 1400) || defined(UNDER_CE) typedef int intptr_t; #endif + /* GetProcAddress doesn't exist in A/W variants under desktop Windows */ + #ifndef UNDER_CE + #define GetProcAddressA GetProcAddress + #endif /* Java->C glue code: * Java package: com.sun.gluegen.runtime.WindowsDynamicLinkerImpl @@ -38,26 +44,24 @@ Java_com_sun_gluegen_runtime_WindowsDynamicLinkerImpl_GetLastError__(JNIEnv *env /* Java->C glue code: * Java package: com.sun.gluegen.runtime.WindowsDynamicLinkerImpl - * Java method: long GetProcAddress(long hModule, java.lang.String lpProcName) - * C function: PROC GetProcAddress(HANDLE hModule, LPCSTR lpProcName); + * Java method: long GetProcAddressA(long hModule, java.lang.String lpProcName) + * C function: PROC GetProcAddressA(HANDLE hModule, LPCSTR lpProcName); */ JNIEXPORT jlong JNICALL -Java_com_sun_gluegen_runtime_WindowsDynamicLinkerImpl_GetProcAddress__JLjava_lang_String_2(JNIEnv *env, jclass _unused, jlong hModule, jstring lpProcName) { - const char* _UTF8lpProcName = NULL; +Java_com_sun_gluegen_runtime_WindowsDynamicLinkerImpl_GetProcAddressA__JLjava_lang_String_2(JNIEnv *env, jclass _unused, jlong hModule, jstring lpProcName) { + const char* _strchars_lpProcName = NULL; PROC _res; if (lpProcName != NULL) { - if (lpProcName != NULL) { - _UTF8lpProcName = (*env)->GetStringUTFChars(env, lpProcName, (jboolean*)NULL); - if (_UTF8lpProcName == NULL) { + _strchars_lpProcName = (*env)->GetStringUTFChars(env, lpProcName, (jboolean*)NULL); + if (_strchars_lpProcName == NULL) { (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/OutOfMemoryError"), - "Failed to get UTF-8 chars for argument \"lpProcName\" in native dispatcher for \"GetProcAddress\""); + "Failed to get UTF-8 chars for argument \"lpProcName\" in native dispatcher for \"GetProcAddressA\""); return 0; } - } } - _res = GetProcAddress((HANDLE) (intptr_t) hModule, (LPCSTR) _UTF8lpProcName); + _res = GetProcAddressA((HANDLE) (intptr_t) hModule, (LPCSTR) _strchars_lpProcName); if (lpProcName != NULL) { - (*env)->ReleaseStringUTFChars(env, lpProcName, _UTF8lpProcName); + (*env)->ReleaseStringUTFChars(env, lpProcName, _strchars_lpProcName); } return (jlong) (intptr_t) _res; } @@ -65,26 +69,25 @@ Java_com_sun_gluegen_runtime_WindowsDynamicLinkerImpl_GetProcAddress__JLjava_lan /* Java->C glue code: * Java package: com.sun.gluegen.runtime.WindowsDynamicLinkerImpl - * Java method: long LoadLibraryA(java.lang.String lpLibFileName) - * C function: HANDLE LoadLibraryA(LPCSTR lpLibFileName); + * Java method: long LoadLibraryW(java.lang.String lpLibFileName) + * C function: HANDLE LoadLibraryW(LPCWSTR lpLibFileName); */ JNIEXPORT jlong JNICALL -Java_com_sun_gluegen_runtime_WindowsDynamicLinkerImpl_LoadLibraryA__Ljava_lang_String_2(JNIEnv *env, jclass _unused, jstring lpLibFileName) { - const char* _UTF8lpLibFileName = NULL; +Java_com_sun_gluegen_runtime_WindowsDynamicLinkerImpl_LoadLibraryW__Ljava_lang_String_2(JNIEnv *env, jclass _unused, jstring lpLibFileName) { + jchar* _strchars_lpLibFileName = NULL; HANDLE _res; if (lpLibFileName != NULL) { - if (lpLibFileName != NULL) { - _UTF8lpLibFileName = (*env)->GetStringUTFChars(env, lpLibFileName, (jboolean*)NULL); - if (_UTF8lpLibFileName == NULL) { + _strchars_lpLibFileName = (jchar *) calloc((*env)->GetStringLength(env, lpLibFileName) + 1, sizeof(jchar)); + if (_strchars_lpLibFileName == NULL) { (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/OutOfMemoryError"), - "Failed to get UTF-8 chars for argument \"lpLibFileName\" in native dispatcher for \"LoadLibraryA\""); + "Could not allocate temporary buffer for copying string argument \"lpLibFileName\" in native dispatcher for \"LoadLibraryW\""); return 0; } - } + (*env)->GetStringRegion(env, lpLibFileName, 0, (*env)->GetStringLength(env, lpLibFileName), _strchars_lpLibFileName); } - _res = LoadLibraryA((LPCSTR) _UTF8lpLibFileName); + _res = LoadLibraryW((LPCWSTR) _strchars_lpLibFileName); if (lpLibFileName != NULL) { - (*env)->ReleaseStringUTFChars(env, lpLibFileName, _UTF8lpLibFileName); + free((void*) _strchars_lpLibFileName); } return (jlong) (intptr_t) _res; } |