【问题标题】:Calling WinMain from Java : Possible ? Any other way?从 Java 调用 WinMain:可能吗?还有什么办法吗?
【发布时间】:2012-05-29 11:51:06
【问题描述】:

我如何从 java 调用这个方法:

 WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

是否可以从 java 调用 WinMain ?我希望该函数中的参数值与直接运行 c++ 程序时的值相同。我想链接一个.dll,其入口点就是这个函数。

【问题讨论】:

标签: java c++ winapi java-native-interface winmain


【解决方案1】:

这是一个坏主意,原因有很多。

WinMain 很特别

mainDllMain,这些功能比看起来要多。

与天真的方法相反,WinMain 不是堆栈上的“第一个”函数。它是代码开发人员可编写的第一个函数。但是如果你去调试,你会发现WinMain之前和之后发生了很多事情。

其中包括 C++ 全局对象的构造/销毁、使用 atexit C API 注册的函数等,但您可以肯定那里发生了很多特定于 Windows 平台的事情。

那么,如果它是WinMain,那么您很可能在内部某处有一个消息循环。它很可能会干扰您自己的(您的 Java 应用程序是 GUI 应用程序吗?)

HINSTANCE 不是可选的

你会给WinMain什么参数值?

第一个 HINSTANCE 参数非常重要,可以由您尝试启动的可执行文件的代码使用。您不能只提供一些随机值并期望它起作用。您可以检索 Java 进程的 HINSTANCE,但我怀疑您不会喜欢这个结果。

隐藏变量不是可选的

假设您成功调用了程序的 WinMain。这个程序会期望一些东西在那里(见WinMain是特殊的部分)。其中,GetCommandLine() API 函数的结果,可以在你的 C++ 程序中使用。

WinMain 用于进程,而不是 DLL

是否可以从 java 调用 WinMain ?我希望该函数中参数的值与直接运行 c++ 程序时的值相同。我想链接一个入口点是这个函数的.dll

您是否要“启动”一个 DLL,其入口点是 WinMain?我猜是哪里出了问题。 WinMainmain 是 Windows 上进程的标准入口点,而不是 DLL。 DLL 入口点通常是DllMain,它们有不同的原型。

结论

我不知道您为什么需要在与 Java 启动器相同的进程中启动可执行文件,但我相信您做错了什么。

就像mikera在他的answer中写的那样,你最好使用Java API来启动一个进程。

【讨论】:

  • "DLL 入口点通常是 DllMain" 。我不知道!这就是我使用WinMain的原因
  • “这是代码开发人员可编写的第一个函数”在一般情况下这是正确的,但您可以在大多数编译器上覆盖 CRT 入口点,从而完全跳过 WinMain跨度>
  • @Suhail Gupta : DllMain 函数与 WinMain 函数不同。它的调用方式不同,它有不同的约束等。所以,不要将 DllMain 用作 WinMain。相反,如果您可以控制您的库,请使用您想要的原型创建一些导出函数,如“MyOwnEntryPoint”,然后像普通函数一样调用它。
  • @Necrolis :当然,您是对的(请注意,我在答案中提供的 WinMain 链接中对此进行了解释)。但我没有按那个特定的问题,因为原来的问题还有其他问题要解决。
  • can you help answer this question 这个问题是基于链接中的问题
【解决方案2】:

应该可以通过JNA:

但是在我看来,它仍然像是一种设计味道.....为什么要从 Java 程序调用 WinMain(标准 Windows 应用程序入口点)?为什么不直接Runtime.exec()呢?

【讨论】:

  • Runtime.exec() : 我不想启动单独的进程,但希望在dlljava 程序之间进行通信
  • 除非我错了,在 WinMain 之前和之后有很多代码,所以直接调用 WinMain 会至少让一些全局变量未初始化和/或未销毁。我什至不确定它是否会起作用
  • @SuhailGupta:如果您不想启动单独的进程,为什么要调用 WinMain 与正在运行的 Windows 程序进行通信?我对你的目标到底是什么感到困惑。请澄清。
  • @Hovercraft Full Of Eels 在调用用 C++ 编写的本机代码之前,我不想完成无法完成的任务。到目前为止,本机代码是一个独立的应用程序。As the C++ application starts WinMain is called and does it work. One of the first statement in my WinMain method is SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0) and there is also a message loop in there。现在我想从 java 调用这段代码。 (将其链接为 dll) 在某些时候,我会让这段代码返回一些值。
  • 如果你想创建自己的 Window 的键盘钩子,那不是这样做的。如果您想与现有的 C++ 应用程序进行通信,那不是这样做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
  • 2014-07-01
  • 2010-12-15
相关资源
最近更新 更多