C++创建jni 并且利用rundll32.exe调试jni程序

eclipse 下新建工程 ctool

建立包  com.c.utils

新建类 ProxyUtil.java

内容如下

package com.c.utils;

public class ProxyUtil {

static 

{

System.loadLibrary("cdll");

}

public native String getIEProxy();

public static void main(String[] args) {

ProxyUtil util=new ProxyUtil();

System.out.println(util.getIEProxy());

}

}

cmd  进入 src/com/c/utils  输入命令 javac ProxyUtil.java

cmd  cd .. 命令 进入src 下  输入命令 javah ProxyUtil

src下会生成 com_c_utils_ProxyUtil.h文件 

建立工程 configDLL

源文件下  configDll.def  这个是个工程定义文件

添加 com_c_utils_ProxyUtil.h文件到dll工程目录下

同时 复制一份 com_c_utils_ProxyUtil.h 修改名称为 com_c_utils_ProxyUtil.cpp

vs2005中添加文件到工程中 

拷贝 jdk/include 目录下的所有头文件到 dll工程目录下 添加文件到工程中

或则 在dll工程下新建目录res  vs2005中点击 工具 --选项--项目和解决方案--vc++ 目录 -- 包含文件 --指定你的 dll目录/res

同时在com_c_utils_ProxyUtil.cpp文件前面添加

#include "StdAfx.h"

#include "jni.h"

#include "jvmti.h"

#include "jawt.h"

#include "stdafx.h"

#include "jawt_md.h"

#include "jdwpTransport.h"

#include "jni_md.h"

#include "wininet.h"

#include <atlbase.h>

#include <atlconv.h>

#include <atlstr.h>

#include <iostream>

using namespace std;

#pragma comment(lib,"Wininet.lib")

同时 JNIEXPORT jstring JNICALL Java_com_c_utils_ProxyUtil_getIEProxy

(JNIEnv *, jobject);

修改为  

JNIEXPORT jstring JNICALL Java_com_c_utils_ProxyUtil_getIEProxy

(JNIEnv *, jobject){

//添加内容

}

下面是我获取代理的代码

jstring chartoJstring(JNIEnv* env, const char* pat)

{

       jclass strClass = env->FindClass("Ljava/lang/String;");

       jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");

       jbyteArray bytes = env->NewByteArray(strlen(pat));

       env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);

       jstring encoding = env->NewStringUTF("utf-8");

       return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);

}

JNIEXPORT jstring JNICALL Java_com_c_utils_ProxyUtil_getIEProxy

(JNIEnv *env, jobject){

DWORD dwBufSize = 1024;

BYTE buf[1024] = {0};

INTERNET_PROXY_INFO * pInfo = (INTERNET_PROXY_INFO *)buf;

if(!InternetQueryOptionA(NULL, INTERNET_OPTION_PROXY, (LPVOID)pInfo, &dwBufSize))

    {

return chartoJstring(env,"1");

    } 

char *pChar = (char *)pInfo->lpszProxy;

return chartoJstring(env,pChar);

}

如果需要使用 调试的话 

在 方法下面 添加一个方法

void main(){

MessageBox(NULL,L"sdff",L"sfsf",MB_OK);

Java_com_c_utils_ProxyUtil_getIEProxy(NULL,NULL);

}

修改configDll.def

内容修改为 

LIBRARY "configDll"

EXPORTS

    Java_com_c_utils_ProxyUtil_getIEProxy

    main

然后生成解决方案 

利用 vs的工具  默认路径 C:/Program Files/Microsoft Visual Studio 8/Common7/Tools/Bin/Depends.Exe

打开 生成的 configDll.dll查看dll是否有两个输出 就是configDll.def中定义的

调试:

在main方法中打一个断点 打在messagebox 后面

打开cmd命令 输入

rundll32.exe "D:/bdlpworkspace/ctool/c/ConfigDll/debug/ExportDll.dll",main //意思就是执行dll中导出的main方法

回车后会马上弹出  sdff   

不要立即点击确定  vs中操作   工具 ---附加到进程 ---选中rundll32.exe  点击附加按钮 

然后点击之前弹出框的 确定按钮 此时代码上已经出现了调试  按 F11  一句句调试 

如果你想看内存中的值   将执行完后的变量 拖入 内存窗口的文本框中 就可以看到 (这个有利于查看宽字节和窄字节造成的乱码问题)

原文地址:https://www.cnblogs.com/liaomin416100569/p/9331602.html