以下代码的java等效代码是什么?

时间:2012-04-10 04:30:14

标签: java c assembly jna equivalent

我正在使用JNA来调用user32.dll和kernel32.dll的方法。它现在工作正常。我遇到了一些问题,我知道我必须调用这个方法。

void SendCommandToConsole( char* Cmd )
{
    DWORD dwCall = 0x004C1030;
    __asm
    {
        push Cmd;
        push 0;
        call dwCall;
    }
}

SendCommandToConsole ( "rp 2000" );

但我甚至不知道它是什么? __asm在做什么?

如果我使用的标签不正确,请添加适当的标签。 :)

修改的 建议添加.Net和C#标签。上面的代码在C#或.NET中,可能是具有该语言知识的人可以告诉我们它实际上是什么,以及我们如何在java中执行此操作。

6 个答案:

答案 0 :(得分:5)

只是为了展示幕后发生的事情:

您的电话:

SendCommandToConsole(“rp 2000”);

使用类型为(char * Cmd)的参数调用函数(SendCommandToConsole)。

在上面的例子中,(char * Cmd)等于“rp 2000”的字符串(sic)。

现在发生的事情是,更高级别的语言(在您的示例中为Java)需要告诉低级语言如何用他们理解的语言解释他们的指令。

所以上面的示例(“我想用”rp 2000“的字符串参数调用函数”SendCommandToConsole“),意味着我们需要与低级语言进行通信:

  • “uppity-ups希望我们执行命令”。 “哦,是的,哪一个?”
  • “他们告诉我'SendCommandToConsole'”
  • “哦,那个家伙?他住在地址'0x004C1030'这里。”
  • “哦,你知道这个家伙的地址吗?你能提供这个包吗? 高兴的想要交付?“
  • “当然可以,但他只接受特定订单的包裹,并且 只有某种类型。“
  • “没问题,我的清单就在这里......让我们来看看吧 符合老兄的要求。“

“首先,那个地址的家伙只想知道两件事情,他们必须按顺序排列:

  • 你想让我做什么,
  • 我将结果报告给谁?“

“好的,这很容易”

我会断言我希望他做什么:

  • “CMD”
  • 现在我要断言我希望他将结果报告给:“没有人(0)”

好吧,我会打电话给你......你现在可以继续你的一天。

(因为这是一个“无效”的回报,这意味着你不关心交易的结果)

答案 1 :(得分:2)

这意味着接下来是汇编代码块。

dwCall是指向一个带有一个参数的汇编过程的指针 - >指向堆栈上零终止字节数组的指针。为了正确调用它,你必须将指针推到堆栈上,你只能通过汇编程序来完成。

答案 2 :(得分:2)

在JNA中,您可以使用Function.getFunction(Pointer)来获取可用于控制特定地址上的调用的对象。

Function dwCall = Function.getFunction(new Pointer(0x12345678));
String CMD = "SomeCommand";
Integer ARG = new Integer(0);
dwCall.invoke(void.class, new Object[CMD, ARG]);

假设该函数使用C调用约定,上面的代码将起作用。最终,您可能希望动态查找函数地址而不是硬编码,并且您可能希望使用JNA Callback而不是直接调用Function对象,但上面的代码提供了您要求的简单功能for(你应该改写原来的问题;你不想执行汇编代码,你想在给定地址调用函数)。

使用JNA回调映射将允许您更自然地调用该函数。

// Use StdCallCallback if the function called uses stdcall rather than cdecl
public class MyCallback extends Callback {
    void invoke(String cmd, int arg);
}

Pointer addr = new Pointer(0x1235678);
MyCallback cb = (MyCallback)CallbackReference.getCallback(MyCallback.class, addr);
cb.invoke("SomeCommand", 0);

请注意,这两个示例都假设您已经使用JNA加载有问题的DLL,通常是通过Native.loadLibrary()

另请注意,签名实际上可能是void dwCall(int arg, String cmd); cdecl和stdcall约定从右到左推送堆栈上的参数,目前我的想法还不够清晰,无法通过正确映射...

答案 3 :(得分:1)

没有Java等价物,Java不允许这种低级控制。您需要将C代码编译为DLL并使用JNA / JNI来调用它。

编辑1:以上仅适用于汇编代码。有关使用JNA在地址上调用stdcall或cdecl函数的信息,请参阅techomage的回复。

__asm块允许您在C源文件中使用程序集。汇编代码调用地址0x004C1030处的函数(无论函数是什么)通过指针传递字符串和零作为参数。

直接调用地址是个坏主意。你可能不会得到你期望的东西,除非你知道程序的低级内部和你的操作系统真的很好。调用它很可能会导致程序崩溃。

答案 4 :(得分:0)

为什么不只是调用SendCommandToConsole()函数?该函数正在做的是进行Windows系统调用而你不应该编写一个执行该操作的函数,你应该调用一个函数来执行该操作。

答案 5 :(得分:0)

我想真正的问题是" rp 2000"做?如果它使用参数2000运行rp.exe,那么你可以使用java.lang.Runtime来做同样的事情。如果我们知道它做了什么,那么java中可能会有一些东西可以做到。