提交 390a2806 编写于 作者: D dholmes

7200297: agent code does not handle multiple boot library path elements correctly

Summary: When bug 6819213 was fixed it enabled sun.boot.library.path property to contain multiple paths. Code in agents does not handle multiple paths when attempting to find dependent shared libs.
Reviewed-by: dholmes, sspitsyn, dsamersoff
Contributed-by: NBill Pittore <bill.pittore@oracle.com>
上级 20bc15e8
/* /*
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "debugLoop.h" #include "debugLoop.h"
#include "bag.h" #include "bag.h"
#include "invoker.h" #include "invoker.h"
#include "sys.h"
/* How the options get to OnLoad: */ /* How the options get to OnLoad: */
#define XDEBUG "-Xdebug" #define XDEBUG "-Xdebug"
...@@ -201,6 +202,8 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved) ...@@ -201,6 +202,8 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
jint jvmtiCompileTimeMajorVersion; jint jvmtiCompileTimeMajorVersion;
jint jvmtiCompileTimeMinorVersion; jint jvmtiCompileTimeMinorVersion;
jint jvmtiCompileTimeMicroVersion; jint jvmtiCompileTimeMicroVersion;
char *boot_path = NULL;
char npt_lib[MAXPATHLEN];
/* See if it's already loaded */ /* See if it's already loaded */
if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) { if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
...@@ -227,18 +230,6 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved) ...@@ -227,18 +230,6 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
vmInitialized = JNI_FALSE; vmInitialized = JNI_FALSE;
gdata->vmDead = JNI_FALSE; gdata->vmDead = JNI_FALSE;
/* Npt and Utf function init */
NPT_INITIALIZE(&(gdata->npt), NPT_VERSION, NULL);
if (gdata->npt == NULL) {
ERROR_MESSAGE(("JDWP: unable to initialize NPT library"));
return JNI_ERR;
}
gdata->npt->utf = (gdata->npt->utfInitialize)(NULL);
if (gdata->npt->utf == NULL) {
ERROR_MESSAGE(("JDWP: UTF function initialization failed"));
return JNI_ERR;
}
/* Get the JVMTI Env, IMPORTANT: Do this first! For jvmtiAllocate(). */ /* Get the JVMTI Env, IMPORTANT: Do this first! For jvmtiAllocate(). */
error = JVM_FUNC_PTR(vm,GetEnv) error = JVM_FUNC_PTR(vm,GetEnv)
(vm, (void **)&(gdata->jvmti), JVMTI_VERSION_1); (vm, (void **)&(gdata->jvmti), JVMTI_VERSION_1);
...@@ -277,6 +268,24 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved) ...@@ -277,6 +268,24 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
forceExit(1); /* Kill entire process, no core dump wanted */ forceExit(1); /* Kill entire process, no core dump wanted */
} }
JVMTI_FUNC_PTR(gdata->jvmti, GetSystemProperty)
(gdata->jvmti, (const char *)"sun.boot.library.path",
&boot_path);
dbgsysBuildLibName(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
/* Npt and Utf function init */
NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
jvmtiDeallocate(boot_path);
if (gdata->npt == NULL) {
ERROR_MESSAGE(("JDWP: unable to initialize NPT library"));
return JNI_ERR;
}
gdata->npt->utf = (gdata->npt->utfInitialize)(NULL);
if (gdata->npt->utf == NULL) {
ERROR_MESSAGE(("JDWP: UTF function initialization failed"));
return JNI_ERR;
}
/* Parse input options */ /* Parse input options */
if (!parseOptions(options)) { if (!parseOptions(options)) {
/* No message necessary, should have been printed out already */ /* No message necessary, should have been printed out already */
......
/* /*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -70,8 +70,13 @@ vprint_message(FILE *fp, const char *prefix, const char *suffix, ...@@ -70,8 +70,13 @@ vprint_message(FILE *fp, const char *prefix, const char *suffix,
len = (int)strlen((char*)utf8buf); len = (int)strlen((char*)utf8buf);
/* Convert to platform encoding (ignore errors, dangerous area) */ /* Convert to platform encoding (ignore errors, dangerous area) */
(void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf, if (gdata->npt != NULL) {
utf8buf, len, pbuf, MAX_MESSAGE_LEN); (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
utf8buf, len, pbuf, MAX_MESSAGE_LEN);
} else {
/* May be called before NPT is initialized so don't fault */
strncpy(pbuf, (char*)utf8buf, len);
}
(void)fprintf(fp, "%s%s%s", prefix, pbuf, suffix); (void)fprintf(fp, "%s%s%s", prefix, pbuf, suffix);
} }
......
/* /*
* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -144,7 +144,9 @@ loadTransport(char *name, jdwpTransportEnv **transportPtr) ...@@ -144,7 +144,9 @@ loadTransport(char *name, jdwpTransportEnv **transportPtr)
/* First, look in sun.boot.library.path. This should find the standard /* First, look in sun.boot.library.path. This should find the standard
* dt_socket and dt_shmem transport libraries, or any library * dt_socket and dt_shmem transport libraries, or any library
* that was delivered with the J2SE. * that was delivered with the J2SE.
* Note: Java property sun.boot.library.path contains a single directory. * Note: Since 6819213 fixed, Java property sun.boot.library.path can
* contain multiple paths. Dll_dir is the first entry and
* -Dsun.boot.library.path entries are appended.
*/ */
libdir = gdata->property_sun_boot_library_path; libdir = gdata->property_sun_boot_library_path;
if (libdir == NULL) { if (libdir == NULL) {
......
/* /*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include "jni.h" #include "jni.h"
#include "jvmti.h" #include "jvmti.h"
#include "classfile_constants.h" #include "classfile_constants.h"
#include "jvm_md.h"
#ifndef SKIP_NPT #ifndef SKIP_NPT
#include "npt.h" /* To get NptEnv for doing character conversions */ #include "npt.h" /* To get NptEnv for doing character conversions */
......
/* /*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -1899,6 +1899,7 @@ load_library(char *name) ...@@ -1899,6 +1899,7 @@ load_library(char *name)
*/ */
getSystemProperty("sun.boot.library.path", &boot_path); getSystemProperty("sun.boot.library.path", &boot_path);
md_build_library_name(lname, FILENAME_MAX, boot_path, name); md_build_library_name(lname, FILENAME_MAX, boot_path, name);
jvmtiDeallocate(boot_path);
handle = md_load_library(lname, err_buf, (int)sizeof(err_buf)); handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
if ( handle == NULL ) { if ( handle == NULL ) {
/* This may be necessary on Windows. */ /* This may be necessary on Windows. */
...@@ -1941,6 +1942,9 @@ lookup_library_symbol(void *library, char **symbols, int nsymbols) ...@@ -1941,6 +1942,9 @@ lookup_library_symbol(void *library, char **symbols, int nsymbols)
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved) Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{ {
char *boot_path = NULL;
char npt_lib[JVM_MAXPATHLEN];
/* See if it's already loaded */ /* See if it's already loaded */
if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) { if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
HPROF_ERROR(JNI_TRUE, "Cannot load this JVM TI agent twice, check your java command line for duplicate hprof options."); HPROF_ERROR(JNI_TRUE, "Cannot load this JVM TI agent twice, check your java command line for duplicate hprof options.");
...@@ -1957,9 +1961,15 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved) ...@@ -1957,9 +1961,15 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
gdata->jvm = vm; gdata->jvm = vm;
/* Get the JVMTI environment */
getJvmti();
#ifndef SKIP_NPT #ifndef SKIP_NPT
getSystemProperty("sun.boot.library.path", &boot_path);
/* Load in NPT library for character conversions */ /* Load in NPT library for character conversions */
NPT_INITIALIZE(&(gdata->npt), NPT_VERSION, NULL); md_build_library_name(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
jvmtiDeallocate(boot_path);
NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
if ( gdata->npt == NULL ) { if ( gdata->npt == NULL ) {
HPROF_ERROR(JNI_TRUE, "Cannot load npt library"); HPROF_ERROR(JNI_TRUE, "Cannot load npt library");
} }
...@@ -1969,9 +1979,6 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved) ...@@ -1969,9 +1979,6 @@ Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
} }
#endif #endif
/* Get the JVMTI environment */
getJvmti();
/* Lock needed to protect debug_malloc() code, which is not MT safe */ /* Lock needed to protect debug_malloc() code, which is not MT safe */
#ifdef DEBUG #ifdef DEBUG
gdata->debug_malloc_lock = createRawMonitor("HPROF debug_malloc lock"); gdata->debug_malloc_lock = createRawMonitor("HPROF debug_malloc lock");
......
...@@ -54,6 +54,32 @@ ...@@ -54,6 +54,32 @@
#define LIB_SUFFIX "so" #define LIB_SUFFIX "so"
#endif #endif
static void dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
// Based on os_solaris.cpp
char *path_sep = PATH_SEPARATOR;
char *pathname = (char *)pname;
while (strlen(pathname) > 0) {
char *p = strchr(pathname, *path_sep);
if (p == NULL) {
p = pathname + strlen(pathname);
}
/* check for NULL path */
if (p == pathname) {
continue;
}
(void)snprintf(buffer, buflen, "%.*s/lib%s." LIB_SUFFIX, (p - pathname),
pathname, fname);
if (access(buffer, F_OK) == 0) {
break;
}
pathname = p + 1;
*buffer = '\0';
}
}
/* /*
* create a string for the JNI native function name by adding the * create a string for the JNI native function name by adding the
* appropriate decorations. * appropriate decorations.
...@@ -76,16 +102,16 @@ dbgsysBuildLibName(char *holder, int holderlen, char *pname, char *fname) ...@@ -76,16 +102,16 @@ dbgsysBuildLibName(char *holder, int holderlen, char *pname, char *fname)
{ {
const int pnamelen = pname ? strlen(pname) : 0; const int pnamelen = pname ? strlen(pname) : 0;
*holder = '\0';
/* Quietly truncate on buffer overflow. Should be an error. */ /* Quietly truncate on buffer overflow. Should be an error. */
if (pnamelen + (int)strlen(fname) + 10 > holderlen) { if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
*holder = '\0';
return; return;
} }
if (pnamelen == 0) { if (pnamelen == 0) {
(void)snprintf(holder, holderlen, "lib%s." LIB_SUFFIX, fname); (void)snprintf(holder, holderlen, "lib%s." LIB_SUFFIX, fname);
} else { } else {
(void)snprintf(holder, holderlen, "%s/lib%s." LIB_SUFFIX, pname, fname); dll_build_name(holder, holderlen, pname, fname);
} }
} }
......
...@@ -380,6 +380,31 @@ md_ntohl(unsigned l) ...@@ -380,6 +380,31 @@ md_ntohl(unsigned l)
return ntohl(l); return ntohl(l);
} }
static void dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
// Loosely based on os_solaris.cpp
char *pathname = (char *)pname;
while (strlen(pathname) > 0) {
char *p = strchr(pathname, ':');
if (p == NULL) {
p = pathname + strlen(pathname);
}
/* check for NULL path */
if (p == pathname) {
continue;
}
(void)snprintf(buffer, buflen, "%.*s/lib%s" JNI_LIB_SUFFIX,
(p - pathname), pathname, fname);
if (access(buffer, F_OK) == 0) {
break;
}
pathname = p + 1;
*buffer = '\0';
}
}
/* Create the actual fill filename for a dynamic library. */ /* Create the actual fill filename for a dynamic library. */
void void
md_build_library_name(char *holder, int holderlen, char *pname, char *fname) md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
...@@ -389,9 +414,9 @@ md_build_library_name(char *holder, int holderlen, char *pname, char *fname) ...@@ -389,9 +414,9 @@ md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
/* Length of options directory location. */ /* Length of options directory location. */
pnamelen = pname ? strlen(pname) : 0; pnamelen = pname ? strlen(pname) : 0;
*holder = '\0';
/* Quietly truncate on buffer overflow. Should be an error. */ /* Quietly truncate on buffer overflow. Should be an error. */
if (pnamelen + (int)strlen(fname) + 10 > holderlen) { if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
*holder = '\0';
return; return;
} }
...@@ -399,7 +424,7 @@ md_build_library_name(char *holder, int holderlen, char *pname, char *fname) ...@@ -399,7 +424,7 @@ md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
if (pnamelen == 0) { if (pnamelen == 0) {
(void)snprintf(holder, holderlen, "lib%s" JNI_LIB_SUFFIX, fname); (void)snprintf(holder, holderlen, "lib%s" JNI_LIB_SUFFIX, fname);
} else { } else {
(void)snprintf(holder, holderlen, "%s/lib%s" JNI_LIB_SUFFIX, pname, fname); dll_build_name(holder, holderlen, pname, fname);
} }
} }
......
...@@ -36,14 +36,14 @@ ...@@ -36,14 +36,14 @@
#define NPT_LIBNAME "npt" #define NPT_LIBNAME "npt"
#define NPT_INITIALIZE(pnpt,version,options) \ #define NPT_INITIALIZE(path,pnpt,version,options) \
{ \ { \
void *_handle; \ void *_handle; \
void *_sym; \ void *_sym; \
\ \
if ( (pnpt) == NULL ) NPT_ERROR("NptEnv* is NULL"); \ if ( (pnpt) == NULL ) NPT_ERROR("NptEnv* is NULL"); \
*(pnpt) = NULL; \ *(pnpt) = NULL; \
_handle = dlopen(JNI_LIB_NAME(NPT_LIBNAME), RTLD_LAZY); \ _handle = dlopen(path, RTLD_LAZY); \
if ( _handle == NULL ) NPT_ERROR("Cannot open library"); \ if ( _handle == NULL ) NPT_ERROR("Cannot open library"); \
_sym = dlsym(_handle, "nptInitialize"); \ _sym = dlsym(_handle, "nptInitialize"); \
if ( _sym == NULL ) NPT_ERROR("Cannot find nptInitialize"); \ if ( _sym == NULL ) NPT_ERROR("Cannot find nptInitialize"); \
......
/* /*
* Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,11 +32,42 @@ ...@@ -32,11 +32,42 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <io.h>
#include "sys.h" #include "sys.h"
#include "path_md.h" #include "path_md.h"
static void dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
// Based on os_windows.cpp
char *path_sep = PATH_SEPARATOR;
char *pathname = (char *)pname;
while (strlen(pathname) > 0) {
char *p = strchr(pathname, *path_sep);
if (p == NULL) {
p = pathname + strlen(pathname);
}
/* check for NULL path */
if (p == pathname) {
continue;
}
if (*(p-1) == ':' || *(p-1) == '\\') {
(void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
pathname, fname);
} else {
(void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
pathname, fname);
}
if (_access(buffer, 0) == 0) {
break;
}
pathname = p + 1;
*buffer = '\0';
}
}
/* /*
* From system_md.c v1.54 * From system_md.c v1.54
*/ */
...@@ -80,20 +111,17 @@ void ...@@ -80,20 +111,17 @@ void
dbgsysBuildLibName(char *holder, int holderlen, char *pname, char *fname) dbgsysBuildLibName(char *holder, int holderlen, char *pname, char *fname)
{ {
const int pnamelen = pname ? (int)strlen(pname) : 0; const int pnamelen = pname ? (int)strlen(pname) : 0;
const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
*holder = '\0';
/* Quietly truncates on buffer overflow. Should be an error. */ /* Quietly truncates on buffer overflow. Should be an error. */
if (pnamelen + (int)strlen(fname) + 10 > holderlen) { if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
*holder = '\0';
return; return;
} }
if (pnamelen == 0) { if (pnamelen == 0) {
sprintf(holder, "%s.dll", fname); sprintf(holder, "%s.dll", fname);
} else if (c == ':' || c == '\\') {
sprintf(holder, "%s%s.dll", pname, fname);
} else { } else {
sprintf(holder, "%s\\%s.dll", pname, fname); dll_build_name(holder, holderlen, pname, fname);
} }
} }
......
/* /*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -367,28 +367,53 @@ get_last_error_string(char *buf, int len) ...@@ -367,28 +367,53 @@ get_last_error_string(char *buf, int len)
return 0; return 0;
} }
static void dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
// Loosley based on os_windows.cpp
char *pathname = (char *)pname;
while (strlen(pathname) > 0) {
char *p = strchr(pathname, ';');
if (p == NULL) {
p = pathname + strlen(pathname);
}
/* check for NULL path */
if (p == pathname) {
continue;
}
if (*(p-1) == ':' || *(p-1) == '\\') {
(void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
pathname, fname);
} else {
(void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
pathname, fname);
}
if (_access(buffer, 0) == 0) {
break;
}
pathname = p + 1;
*buffer = '\0';
}
}
/* Build a machine dependent library name out of a path and file name. */ /* Build a machine dependent library name out of a path and file name. */
void void
md_build_library_name(char *holder, int holderlen, char *pname, char *fname) md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
{ {
int pnamelen; int pnamelen;
char c;
pnamelen = pname ? (int)strlen(pname) : 0; pnamelen = pname ? (int)strlen(pname) : 0;
c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
*holder = '\0';
/* Quietly truncates on buffer overflow. Should be an error. */ /* Quietly truncates on buffer overflow. Should be an error. */
if (pnamelen + strlen(fname) + 10 > (unsigned int)holderlen) { if (pnamelen + strlen(fname) + 10 > (unsigned int)holderlen) {
*holder = '\0';
return; return;
} }
if (pnamelen == 0) { if (pnamelen == 0) {
sprintf(holder, "%s.dll", fname); sprintf(holder, "%s.dll", fname);
} else if (c == ':' || c == '\\') {
sprintf(holder, "%s%s.dll", pname, fname);
} else { } else {
sprintf(holder, "%s\\%s.dll", pname, fname); dll_build_name(holder, holderlen, pname, fname);
} }
} }
......
/* /*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,30 +33,16 @@ ...@@ -33,30 +33,16 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#define NPT_LIBNAME "npt.dll" #define NPT_LIBNAME "npt"
#define NPT_INITIALIZE(pnpt,version,options) \ #define NPT_INITIALIZE(path,pnpt,version,options) \
{ \ { \
HINSTANCE jvm; \
void *_handle; \ void *_handle; \
void *_sym; \ void *_sym; \
char buf[FILENAME_MAX+32]; \
char *lastSlash; \
\ \
if ( (pnpt) == NULL ) NPT_ERROR("NptEnv* is NULL"); \ if ( (pnpt) == NULL ) NPT_ERROR("NptEnv* is NULL"); \
_handle = NULL; \
*(pnpt) = NULL; \ *(pnpt) = NULL; \
buf[0] = 0; \ _handle = LoadLibrary(path); \
jvm = GetModuleHandle("jvm.dll"); \
if ( jvm == NULL ) NPT_ERROR("Cannot find jvm.dll"); \
GetModuleFileName(jvm, buf, FILENAME_MAX); \
lastSlash = strrchr(buf, '\\'); \
if ( lastSlash != NULL ) { \
*lastSlash = '\0'; \
(void)strcat(buf, "\\..\\"); \
(void)strcat(buf, NPT_LIBNAME); \
_handle = LoadLibrary(buf); \
} \
if ( _handle == NULL ) NPT_ERROR("Cannot open library"); \ if ( _handle == NULL ) NPT_ERROR("Cannot open library"); \
_sym = GetProcAddress(_handle, "nptInitialize"); \ _sym = GetProcAddress(_handle, "nptInitialize"); \
if ( _sym == NULL ) NPT_ERROR("Cannot find nptInitialize"); \ if ( _sym == NULL ) NPT_ERROR("Cannot find nptInitialize"); \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册