ビルドしようとしている C ファイルがありますが、リンカー エラーが発生します。これは、他のソース ファイルで定義されているメソッド定義が見つからないためです。
ここでまさに私がやろうとしているのは、このソース ファイルによって特定されるメソッドの定義を作成することです。私が構築しようとしているメインプログラムであるコードを提供しています。どんな提案でも大歓迎です。
#include<stdio.h>
#include<jni.h>
#include<windows.h>
#include <stdbool.h>
#include "RunnerClass.h"
#include "unistd.h"
#include "apr_getopt.h"
#include "apr_portable.h"
#include "C:\JNItest\src\common\error_debug.h"
#include "C:\JNItest\src\common\event.h"
#include "C:\JNItest\src\common\context.h"
#include "C:\JNItest\src\common\alloc.h"
#include "C:\JNItest\src\core\nxlog.h"
#include "C:\JNItest\src\core\modules.h"
#include "C:\JNItest\src\core\router.h"
#include "C:\JNItest\src\core\ctx.h"
#include "C:\JNItest\src\core\core.h"
#define NX_LOGMODULE NX_LOGMODULE_CORE
static nxlog_t nxlog;
static apr_os_thread_t _nxlog_initializer = 0;
static void WINAPI nx_win32_svc_main(DWORD argc, LPTSTR * argv);
static void WINAPI nx_win32_svc_change(DWORD);
extern void nx_logger_disable_foreground();
static void print_usage();
static void set_configfile();
static bool do_install = FALSE;
static bool do_uninstall = FALSE;
static SERVICE_STATUS svc_status;
static SERVICE_STATUS_HANDLE *svc_status_handle = NULL;
JNIEXPORT void JNICALL Java_RunnerClass_parse_1cmd_1line
(JNIEnv * env, jobject jobj, jint argc, const jstring * const *argv){
char *opt_arg;
int rv;
apr_getopt_t *opt;
int ch;
static apr_getopt_option_t options[] = {
{ "help", 'h', 0, "print help" },
{ "foreground", 'f', 0, "run in foreground" },
{ "stop", 's', 0, "stop a running instance" },
// { "reload", 'r', 0, "reload configuration of a running instance" },
{ "conf", 'c', 1, "configuration file" },
{ "verify", 'v', 0, "verify configuration file syntax" },
{ "install", 'i', 0, "install service available to service manager" },
{ "uninstall", 'u', 0, "uninstall service" },
{ NULL, 0, 1, NULL },
};
apr_getopt_init(&opt, nxlog.pool, argc,(void *) argv);
while ( (rv = apr_getopt_long(opt, options, &ch,(void *) &opt_arg)) == APR_SUCCESS )
{
switch ( ch )
{
case 'c': /* configuration file */
nxlog.cfgfile = apr_pstrdup(nxlog.pool, opt_arg);
break;
case 'f': /* foreground */
nxlog.foreground = TRUE;
break;
case 'h': /* help */
print_usage();
exit(-1);
case 's': /* stop */
nxlog.do_stop = TRUE;
break;
/*
case 'r': // reload
nxlog.do_restart = true;
break;
*/
case 'v': /* verify */
nxlog.verify_conf = TRUE;
nxlog.ctx->ignoreerrors = FALSE;
break;
case 'i': /* install */
do_install = TRUE;
break;
case 'u': /* uninstall */
do_uninstall = TRUE;
break;
default:
print_usage();
exit(-1);
}
}
set_configfile();
if ( (rv != APR_SUCCESS) && (rv !=APR_EOF) )
{
throw(rv ,"Could not parse options");///////////
}
}
JNIEXPORT void JNICALL Java_RunnerClass_nx_1win32_1svc_1stop
(JNIEnv * env, jobject jobj){
SC_HANDLE service_manager = NULL;
SC_HANDLE service_handle = NULL;
SERVICE_STATUS status;
nx_exception_t e;
// Connect to service manager
service_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if ( service_manager == NULL )
{
nx_win32_error("Cannot initialize access to the service manager");
}
try
{
service_handle = OpenService(service_manager, "nxlog", SERVICE_ALL_ACCESS);
if ( service_handle == NULL )
{
nx_win32_error("Couldn't open nxlog service");
}
else
{
if ( QueryServiceStatus(service_handle, &status) )
{
if ( status.dwCurrentState != SERVICE_STOPPED )
{
log_info("Service currenty active - stopping service...");
if ( !ControlService(service_handle, SERVICE_CONTROL_STOP, &status) )
{
nx_win32_error("Couldn't stop service");
}
else
{
Sleep(500);
}
}
else
{
log_error("Service is already stopped");
}
}
// Close connection to service
CloseServiceHandle(service_handle);
}
// Close connection to service manager
CloseServiceHandle(service_manager);
}
catch(e)
{
if ( service_handle != NULL )
{
CloseServiceHandle(service_handle);
}
if ( service_manager != NULL )
{
CloseServiceHandle(service_manager);
}
rethrow(e);
}
}
JNIEXPORT void JNICALL Java_RunnerClass_nx_1win32_1svc_1install
(JNIEnv * env, jobject jobj){
SC_HANDLE service_manager;
SC_HANDLE new_service = NULL;
HKEY regkey;
uint32_t regtype = 0;
char regvalbuf[1024];
uint32_t regvalbufsize = 1024;
char servicename[1024];
// Connect to service manager
service_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if ( service_manager == NULL )
{
nx_win32_error("Cannot initialize access to the service manager");
}
//FIXME use nxlog.ctx.user to invoke service in CreateService
// default in case registry lookup would fail
apr_cpystrn(servicename,
"\"c:\\Program Files\\nxlog\\nxlog.exe\" -c \"c:\\Program Files\\nxlog\\nxlog.conf\"",
sizeof(servicename));
if ( RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\nxlog", ®key) == ERROR_SUCCESS )
{
if ( RegQueryValueEx(regkey, "installdir", 0,(void *) ®type,(unsigned char *) regvalbuf,(void *) ®valbufsize) == ERROR_SUCCESS )
{
if ( regtype == REG_SZ )
{
apr_snprintf(servicename, sizeof(servicename), "\"%snxlog.exe\"", regvalbuf);
}
}
RegCloseKey(regkey);
}
// Install the new service
new_service = CreateService(service_manager, "nxlog", "nxlog",
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
servicename, NULL, NULL,
"eventlog\0", NULL, NULL);
if ( new_service == NULL )
{
nx_win32_error("Couldn't create service");
}
else
{
CloseServiceHandle(new_service);
log_info("Service successfully installed");
}
// Close the connection to service manager
CloseServiceHandle(service_manager);
}
JNIEXPORT void JNICALL Java_RunnerClass_nx_1win32_1svc_1uninstall
(JNIEnv * env, jobject jobj){
SC_HANDLE service_manager = NULL;
SC_HANDLE service_handle = NULL;
SERVICE_STATUS query_status;
nx_exception_t e;
// Connect to service manager
service_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if ( service_manager == NULL )
{
nx_win32_error("Cannot initialize access to the service manager");
}
try
{
// Connect to service
service_handle = OpenService(service_manager, "nxlog", SERVICE_ALL_ACCESS | DELETE);
if ( service_handle == NULL )
{
nx_win32_error("Couldn't open nxlog service");
}
else
{
// Check that the service is stopped
if ( QueryServiceStatus(service_handle, &query_status) &&
(query_status.dwCurrentState == SERVICE_RUNNING) )
{
throw_msg("Service is running, please stop it first.");
}
else
{ // we can remove
if ( DeleteService(service_handle) == FALSE )
{
nx_win32_error("Couldn't delete service");
}
else
{
log_info("Service successfully uninstalled");
}
}
// Close connection to service
CloseServiceHandle(service_handle);
}
// Close connection to service manager
CloseServiceHandle(service_manager);
}
catch(e)
{
if ( service_handle != NULL )
{
CloseServiceHandle(service_handle);
}
if ( service_manager != NULL )
{
CloseServiceHandle(service_manager);
}
rethrow(e);
}
}
JNIEXPORT void JNICALL Java_RunnerClass_nx_1win32_1svc_1main
(JNIEnv * env, jobject jobj, jint argc, jstring *argv){
nx_context_t thread_context;
nx_exception_t e;
if ( _nxlog_initializer == 0 )
{ // running from service manager
ASSERT(nx_init((void *)&argc, (void *)&argv, NULL) == TRUE);
nxlog_init(&nxlog);
nx_logger_disable_foreground();
}
else if ( _nxlog_initializer != apr_os_thread_current() )
{
// service dispatcher runs in a new thread, we need
// to initialize the exception context.
_nxlog_initializer = apr_os_thread_current();
memset(&thread_context, 0, sizeof(nx_context_t));
init_exception_context(&thread_context.exception_context);
apr_threadkey_private_set(&thread_context, nx_get_context_key());
}
log_debug("nx_win32_svc_main");
try
{
// read config cache
nx_config_cache_read();
log_debug("nxlog cache read");
// load DSO and read and verify module config
nx_ctx_config_modules(nxlog.ctx);
log_debug("nxlog config OK");
// initialize modules
nx_ctx_init_modules(nxlog.ctx);
// initialize log routes
nx_ctx_init_routes(nxlog.ctx);
nx_ctx_init_jobs(nxlog.ctx);
nx_ctx_restore_queues(nxlog.ctx);
// setup threadpool
nxlog_create_threads(&nxlog);
// start modules
nx_ctx_start_modules(nxlog.ctx);
if ( nxlog.foreground != TRUE )
{
// register to service manager
svc_status_handle = (void *)RegisterServiceCtrlHandler("nxlog", nx_win32_svc_change);
if ( svc_status_handle == 0 )
{
nx_win32_error("RegisterServiceCtrlHandler() failed, couldn't register the service control handler");
}
// Signal to svc manager that we are running
svc_status.dwWin32ExitCode = 0;
svc_status.dwServiceSpecificExitCode = 0;
svc_status.dwCheckPoint = 0;
svc_status.dwWaitHint = 0;
svc_status.dwServiceType = SERVICE_WIN32;
svc_status.dwCurrentState = SERVICE_RUNNING;
svc_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if ( SetServiceStatus(*svc_status_handle, &svc_status) == FALSE )
{
nx_win32_error("Cannot send start service status update");
}
}
//log_info(PACKAGE"-"VERSION_STRING" started");
}
catch(e)
{
log_exception(e);
log_error("exiting...");
svc_status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(*svc_status_handle, &svc_status);
exit(e.code);
}
// mainloop
nxlog_mainloop(&nxlog, FALSE);
nxlog_shutdown(&nxlog);
if ( nxlog.foreground != TRUE )
{
// Signal back that we are stopped
svc_status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(*svc_status_handle, &svc_status);
}
nxlog_exit_function();
}
JNIEXPORT void JNICALL Java_RunnerClass_nx_1win32_1svc_1dispatch
(JNIEnv * env, jobject jobj){
static SERVICE_TABLE_ENTRY svc_dispatch_table[] =
{
{ "nxlog", NULL },
{ NULL, NULL }
};
if ( StartServiceCtrlDispatcher(svc_dispatch_table) == FALSE )
{
nx_win32_error("Cannot start service dispatcher");
}
}
JNIEXPORT void JNICALL Java_RunnerClass_nx_1win32_1svc_1start
(JNIEnv * env, jobject jobj, jint argc, jstring argv){
SC_HANDLE service_manager = NULL;
SC_HANDLE service_handle = NULL;
SERVICE_STATUS status;
nx_exception_t e;
// Connect to service manager
service_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if ( service_manager == NULL )
{
nx_win32_error("Cannot initialize access to the service manager");
}
try
{
service_handle = OpenService(service_manager, "nxlog", SERVICE_ALL_ACCESS);
if ( service_handle == NULL )
{
nx_win32_error("Couldn't open nxlog service");
}
else
{
if ( QueryServiceStatus(service_handle, &status) )
{
if ( status.dwCurrentState != SERVICE_RUNNING )
{
log_info("Service not running - starting service...");
if ( StartService(service_handle, argc,(void *) argv) == 0 )
{
nx_win32_error("Failed to start nxlog service");
}
}
else
{
log_error("Service is already running");
}
}
// Close connection to service
CloseServiceHandle(service_handle);
}
// Close connection to service manager
CloseServiceHandle(service_manager);
}
catch(e)
{
if ( service_handle != NULL )
{
CloseServiceHandle(service_handle);
}
if ( service_manager != NULL )
{
CloseServiceHandle(service_manager);
}
rethrow(e);
}
}
JNIEXPORT void JNICALL Java_RunnerClass_nxlog_1exit_1function
(JNIEnv * env, jobject jbobj){
static bool exited = FALSE;
if ( exited == TRUE )
{
return;
}
exited = TRUE;
if ( _nxlog_initializer == 0 )
{
return;
}
if ( nxlog.pid != (int) getpid() )
{
return;
}
nx_ctx_free(nxlog.ctx);
apr_pool_destroy(nxlog.pool);
apr_terminate();
}
/* Callback for service changes */
static void WINAPI nx_win32_svc_change(DWORD cmd)
{
// Only STOP command is handled
switch ( cmd )
{
case SERVICE_CONTROL_STOP:
log_warn("stopping nxlog service");
nxlog.terminate_request = TRUE;
// Wait until service stops
while ( svc_status.dwCurrentState != SERVICE_STOPPED )
{
Sleep(500);
}
break;
case SERVICE_CONTROL_INTERROGATE:
// ignore
log_debug("ignoring unsupported service change request: SERVICE_CONTROL_INTERROGATE");
break;
case SERVICE_CONTROL_PAUSE:
log_warn("ignoring unsupported service change request: SERVICE_CONTROL_PAUSE");
break;
case SERVICE_CONTROL_CONTINUE:
log_warn("ignoring unsupported service change request: SERVICE_CONTROL_CONTINUE");
break;
case SERVICE_CONTROL_PARAMCHANGE:
log_warn("ignoring unsupported service change request: SERVICE_CONTROL_PARAMCHANGE");
break;
case 200:
nxlog_dump_info();
break;
case 201:
{
nx_ctx_t *ctx;
log_info("got user control signal, switching to debug loglevel");
ctx = nx_ctx_get();
ctx->loglevel = NX_LOGLEVEL_DEBUG;
}
break;
default:
log_warn("ignoring unsupported service change request (%d)", cmd);
}
}
static void print_usage()
{
printf(/*PACKAGE*/ "-" /*ERSION_STRING*/ "\n"
" usage: "
" nxlog.exe [OPTIONS]\n"
" [-h] print help\n"
" [-f] run in foreground, otherwise try to start the nxlog service\n"
" [-c conffile] specify an alternate config file\n"
" [-i] install service available to service manager\n"
" [-u] uninstall service\n"
" [-s] stop running nxlog service\n"
" [-v] verify configuration file syntax\n"
);
// " [-r] reload configuration of a running instance\n"
}
static void set_configfile()
{
HKEY regkey;
uint32_t regtype = 0;
char regvalbuf[1024];
uint32_t regvalbufsize = 1024;
if ( nxlog.cfgfile != NULL )
{
return;
}
if ( RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\nxlog", ®key) == ERROR_SUCCESS )
{
if ( RegQueryValueEx(regkey, "installdir", 0, (void *)®type,
(unsigned char *) regvalbuf,(void *) ®valbufsize) == ERROR_SUCCESS )
{
if ( regtype == REG_SZ )
{
nxlog.cfgfile = apr_psprintf(nxlog.pool, "%sconf\\nxlog.conf", regvalbuf);
}
}
RegCloseKey(regkey);
}
if ( nxlog.cfgfile == NULL )
{
//nxlog.cfgfile = apr_pstrdup(nxlog.pool, NX_CONFIGFILE);
}
}