我有一个包含一堆静态*lib
文件的库,我希望从中访问它们JNA
(一个Java库,该库允许一个人从JAVA代码中动态调用`dll’),所以有办法神奇地将静态lib更改为dll吗?
代码是使用Visual Studio(相关的希望)进行编译的,我也有适当的头文件。
我无权访问源代码,我也想仅使用免费(如在啤酒中)工具进行操作。
我按照一个匿名人员的建议做了,我做了一个自动转换器(有人建议将_ddlspec(export)放在声明之前并使用此标头编译dll会起作用-嗯,那没有-
也许我做错了-我很普通旧Java程序员;)):
它基本上解析头文件并变成:
SADENTRY SadLoadedMidFiles( HMEM, USHORT usMaxMidFiles, VOID * );
至:
__declspec(dllexport) SADENTRY DLL_WRAPPER_SadLoadedMidFiles(HMEM param0,
USHORT usMaxMidFiles, VOID* param2){
return SadLoadedMidFiles(param0, usMaxMidFiles, param2);
}
这是代码(很可能是它的Regexp滥用,但是可以工作),gui部分取决于MigLayout:
package cx.ath.jbzdak.diesIrae.util.wrappergen;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import static java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Displays a window. In this window you have to specify two things:
* <p/>
* 1. Name of header file that you want to process.
* <p/>
* 2. Name of output files extension will be added automatically. We will override any existing files.
*
* <p/>
* Dependencies: MigLayout
* <p/>
* Actual wrapper generation is done inside WrapperGen class.
* <p/>
* KNOWN ISSUES:
* <p/>
* 1. Ignores preprocessor so may extract finction names that are inside <code>#if false</code>.
* <p/>
* 2. Ignores comments
* <p/>
* 3. May fail to parse werid parameter syntax. . .
*
* Created by IntelliJ IDEA.
* User: Jacek Bzdak
*/
public class WrapperGenerator {
public static final Charset charset = Charset.forName("UTF-8");
WrapperGen generator = new WrapperGen();
// GUI CODE:
File origHeader, targetHeader, targetCpp;
JTextField newHeaderFileName;
JFrame wrapperGeneratorFrame;
{
wrapperGeneratorFrame = new JFrame();
wrapperGeneratorFrame.setTitle("Zamknij mnie!"); //Wrapper generator
wrapperGeneratorFrame.setLayout( new MigLayout("wrap 2, fillx", "[fill,min!]"));
wrapperGeneratorFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ActionListener buttonListener = new ActionListener() {
JFileChooser fileChooser = new JFileChooser();
{
fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
@Override
public boolean accept(File f) {
return f.isDirectory() || f.getName().matches(".*\\.h(?:pp)?");
}
@Override
public String getDescription() {
return "Header files";
}
});
fileChooser.setCurrentDirectory(new File("C:\\Documents and Settings\\jb\\My Documents\\Visual Studio 2008\\Projects\\dll\\dll"));
}
public void actionPerformed(ActionEvent e) {
if(JFileChooser.APPROVE_OPTION == fileChooser.showOpenDialog(wrapperGeneratorFrame)){
origHeader = fileChooser.getSelectedFile();
}
}
};
wrapperGeneratorFrame.add(new JLabel("Original header file"));
JButton jButton = new JButton("Select header file");
jButton.addActionListener(buttonListener);
wrapperGeneratorFrame.add(jButton);
wrapperGeneratorFrame.add(new JLabel("Result files prefix"));
newHeaderFileName = new JTextField("dll_wrapper");
wrapperGeneratorFrame.add(newHeaderFileName);
ActionListener doListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
targetHeader = new File(origHeader.getParentFile(), newHeaderFileName.getText() + ".h");
targetCpp = new File(origHeader.getParentFile(), newHeaderFileName.getText() + ".cpp");
try {
targetHeader.createNewFile();
targetCpp.createNewFile();
generator.reader = new InputStreamReader(new FileInputStream(origHeader),charset);
generator.cppWriter = new OutputStreamWriter(new FileOutputStream(targetCpp), charset);
generator.heaerWriter = new OutputStreamWriter(new FileOutputStream(targetHeader), charset);
generator.parseReader();
} catch (IOException e1) {
e1.printStackTrace();
JOptionPane.showMessageDialog(wrapperGeneratorFrame, "ERROR:" + e1.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
return;
}
}
};
JButton go = new JButton("go");
go.addActionListener(doListener);
wrapperGeneratorFrame.add(go, "skip 1");
}
public static void main(String []args){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
WrapperGenerator wgen = new WrapperGenerator();
JFrame f = wgen.wrapperGeneratorFrame;
wgen.wrapperGeneratorFrame.pack();
Point p = getLocalGraphicsEnvironment().getCenterPoint();
wgen.wrapperGeneratorFrame.setLocation(p.x-f.getWidth()/2, p.y-f.getHeight()/2);
wgen.wrapperGeneratorFrame.setVisible(true);
}
});
}
}
/**
* Does the code parsing and generation
*/
class WrapperGen{
/**
* Method is basically syntax like this: <code>(anything apart from some special chars like #;) functionName(anything)</code>;
* Method declarations may span many lines.
*/
private static final Pattern METHOD_PATTERN =
//1 //2 //params
Pattern.compile("([^#;{}]*\\s+\\w[\\w0-9_]+)\\(([^\\)]*)\\);", Pattern.MULTILINE);
//1 - specifiers - including stuff like __dllspec(export)...
//2 - function name
//3 param list
/**
* Generated functions will have name prefixet with #RESULT_PREFIX
*/
private static final String RESULT_PREFIX = "DLL_WRAPPER_";
/**
* Specifiers of result will be prefixed with #RESULT_SPECIFIER
*/
private static final String RESULT_SPECIFIER = "__declspec(dllexport) ";
Reader reader;
Writer heaerWriter;
Writer cppWriter;
public void parseReader() throws IOException {
StringWriter writer = new StringWriter();
int read;
while((read = reader.read())!=-1){
writer.write(read);
}
reader.close();
heaerWriter.append("#pragma once\n\n\n");
heaerWriter.append("#include \"stdafx.h\"\n\n\n"); //Standard Visual C++ import file.
cppWriter.append("#include \"stdafx.h\"\n\n\n");
Matcher m = METHOD_PATTERN.matcher(writer.getBuffer());
while(m.find()){
System.out.println(m.group());
handleMatch(m);
}
cppWriter.close();
heaerWriter.close();
}
public void handleMatch(Matcher m) throws IOException {
Method meth = new Method(m);
outputHeader(meth);
outputCPP(meth);
}
private void outputDeclaration(Method m, Writer writer) throws IOException {
//writer.append(RESULT_SPECIFIER);
writer.append(m.specifiers);
writer.append(" ");
writer.append(RESULT_PREFIX);
writer.append(m.name);
writer.append("(");
for (int ii = 0; ii < m.params.size(); ii++) {
Parameter p = m.params.get(ii);
writer.append(p.specifiers);
writer.append(" ");
writer.append(p.name);
if(ii!=m.params.size()-1){
writer.append(", ");
}
}
writer.append(")");
}
public void outputHeader(Method m) throws IOException {
outputDeclaration(m, heaerWriter);
heaerWriter.append(";\n\n");
}
public void outputCPP(Method m) throws IOException {
cppWriter.append(RESULT_SPECIFIER);
outputDeclaration(m, cppWriter);
cppWriter.append("{\n\t");
if (!m.specifiers.contains("void") || m.specifiers.matches(".*void\\s*\\*.*")) {
cppWriter.append("return ");
}
cppWriter.append(m.name);
cppWriter.append("(");
for (int ii = 0; ii < m.params.size(); ii++) {
Parameter p = m.params.get(ii);
cppWriter.append(p.name);
if(ii!=m.params.size()-1){
cppWriter.append(", ");
}
}
cppWriter.append(");\n");
cppWriter.append("}\n\n");
}
}
class Method{
private static final Pattern NAME_REGEXP =
//1 //2
Pattern.compile("\\s*(.*)\\s+(\\w[\\w0-9]+)\\s*", Pattern.MULTILINE);
//1 - all specifiers - including __declspec(dllexport) and such ;)
//2 - function name
public final List<Parameter> params;
public final String name;
public final String specifiers;
public Method(Matcher m) {
params = Collections.unmodifiableList(Parameter.parseParamList(m.group(2)));
Matcher nameMather = NAME_REGEXP.matcher(m.group(1));
System.out.println("ALL: " + m.group());
System.out.println("G1: " + m.group(1));
if(!nameMather.matches()){
throw new IllegalArgumentException("for string " + m.group(1));
}
// nameMather.find();
specifiers = nameMather.group(1);
name = nameMather.group(2);
}
}
class Parameter{
static final Pattern PARAMETER_PATTERN =
//1 //2
Pattern.compile("\\s*(?:(.*)\\s+)?([\\w\\*&]+[\\w0-9]*[\\*&]?)\\s*");
//1 - Most probably parameter type and specifiers, but may also be empty - in which case name is empty, and specifiers are in 2
//2 - Most probably parameter type, sometimes prefixed with ** or &* ;), also
// 'char *' will be parsed as grup(1) == char, group(2) = *.
/**
* Used to check if group that represenrs parameter name is in fact param specifier like '*'.
*/
static final Pattern STAR_PATTERN =
Pattern.compile("\\s*([\\*&]?)+\\s*");
/**
* If
*/
static final Pattern NAME_PATTERN =
Pattern.compile("\\s*([\\*&]+)?(\\w[\\w0-9]*)\\s*");
public final String name;
public final String specifiers;
public Parameter(String param, int idx) {
System.out.println(param);
Matcher m = PARAMETER_PATTERN.matcher(param);
String name = null;
String specifiers = null;
if(!m.matches()){
throw new IllegalStateException(param);
}
name = m.group(2);
specifiers = m.group(1);
if(specifiers==null || specifiers.isEmpty()){ //Case that parameter has no name like 'int', or 'int**'
specifiers = name;
name = null;
}else if(STAR_PATTERN.matcher(name).matches()){ //Case that parameter has no name like 'int *'
specifiers += name;
name = null;
}else if(NAME_PATTERN.matcher(name).matches()){ //Checks if name contains part of type like '**ptrData', and extracts '**'
Matcher m2 = NAME_PATTERN.matcher(name);
m2.matches();
if(m2.group(1)!=null){
specifiers += m2.group(1);
name = m2.group(2);
}
}
if(name==null){
name = "param" + idx;
}
this.specifiers = specifiers;
this.name = name;
}
public static List<Parameter> parseParamList(String paramList){
List<Parameter> result = new ArrayList<Parameter>();
String[] params = paramList.split(",");
int idx = 0;
for(String param : params){
Parameter p = new Parameter(param, idx++);
result.add(p);
}
if(result.size()==1){
Parameter p = result.get(0);
if(p.specifiers.matches("\\s*void\\s*")){
return Collections.emptyList();
}
}
return result;
}
}
问题内容: 我有一个第三方库,主要由大量的静态()库文件组成。我可以将其编译为单个库文件,但我确实需要将其作为单个共享库文件。 有什么方法可以将静态文件转换为共享文件?或更笼统地说,是否有一种将大量静态文件和一些目标文件合并为一个文件的好方法? 问题答案: 是否这样做(当然带有适当的-L) 不是吗
要求:在移动设备上查看基于XFA的PDF。 我尝试过的选项: 由于Adobe移动阅读器不支持XFA,因此我可以将XFA展平为静态PDF。我尝试过,但无法使用iText将动态XFA转换为静态PDF。 后来我尝试使用“Adobe PDF”作为打印服务打印XFA表单。这在手动执行时可以正常工作,但在通过代码执行时会以某种方式清除表单数据。 下面是打印任务的示例代码。已为“Adobe PDF”打印服务安装
问题内容: 有没有一种方法可以自动转换此静态方法调用(): 使用以下命令进行此调用: 我知道我可以按照此答案中所述使用此配置代码完成。 我的问题是关于转换 现有的 静态方法调用。理想情况下,我不想配置“收藏夹导入”。 问题答案: 将光标放在方法名称()上,然后按。 这是“添加导入”命令的默认键盘快捷键。您也可以在“源”菜单上找到该命令。
我试图从Scala类创建一个Dll。我正在使用IntelliJ和SBT。我已经找到了一种使用ikvm-converter将.jar文件转换为Dll的方法。现在的问题是:当我在SBT下使用“package”从我的.scala文件中创建一个.jar文件,然后尝试用ikvmc将其转换为Dll时,结果库在集成到C#中时是空的... 向你问好Christoph
我试图保存一个字符串在希伯来文文件,同时有文件ANSI编码。恐怕所有的尝试都失败了。 PHP文件本身是UTF-8 这是我正在尝试的代码: 由于某种原因,返回false。 另一次尝试是: 这返回一个空字符串。当这不起作用时,将输出字符集更改为Windows-1255的工作。所以函数本身工作,但由于某种原因,它不转换为1252。 我运行这个函数之前和之后的和打印的结果 在图标之前编码是UTF-8,在图
问题内容: 在这一点上,我真的很沮丧。我有一个现有的hg存储库,其中已有几个月的编码历史,因此我想将其放入私有的Github存储库中,以便从那里进行处理。不幸的是,我使用Windows,但似乎找不到 任何 方法来转换实际上可以正常使用的存储库。几乎可以在网上找到的所有帮助和建议似乎都假设我是从某种* nix shell运行的,而我不是。 我目前已安装:Windows下的TortoiseHG,Pyt