You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MT4通过DLL调用Java程序闪退问题求助

MT4调用DLL启动Java Jar文件失败,进程一闪而过

我使用Windows 11 Home系统,希望通过标准输入输出管道实现MetaTrader4(MT4)与自研Java应用的通信,当前尝试通过MT4调用DLL来启动.jar文件。但启动MQL脚本并成功导入DLL后,仅出现一闪而过的控制台窗口,任务管理器中也找不到对应线程。

我的代码

Java代码

import javax.swing.*;
public class SystemOutTest {
       public static void main(String[] args) throws InterruptedException {
          JFrame frame = new JFrame("Text Window");
          JLabel label = new JLabel("Hello, World!");
          frame.add(label);
          frame.setSize(200, 100);
          frame.setVisible(true);
          
          Thread.sleep(9000);
       }
}

Delphi/Pascal DLL代码

library JarLauncher;

uses
    Windows, ShellAPI;

function LaunchJar(const AFileName: string; const AArguments: string): Integer; stdcall;

    var
    JavaPath: string;

    begin
        JavaPath := 'C:\Program Files (x86)\Java\jre1.8.0_361\bin\java.exe';
        Result := ShellExecute(
            0,
            nil,
            'java.exe',
            '-Xmx1024M -Xms1024M -jar testpilot.jar',
            nil,
            SW_SHOW
        );
    end;

exports
    LaunchJar;

begin
end.

MQL代码

#import "JarLauncher.dll"
int LaunchJar(string AFileName, string AArguments);
#import

void OnInit()
{
   // string jarFile = "C:\\path\\to\\testpilot.jar";
   string jarFile = "testpilot.jar";
   string arguments = "";
   
   int result = LaunchJar(jarFile, arguments);
   if (result <= 0)
   {
      Print("Failed to launch JAR file!");
   }
   else
   {
      Print(result);
   }
   Sleep(9000);
}

已知信息

  • MT4为32位程序,已将Lazarus、Eclipse及JRE均调整为32位版本,无报错(曾解决ERR 126文件未找到问题,确认MQL可正常找到并执行DLL)
  • MT4控制台输出:
2023.04.15 20:43:28.558    maybeload [DJI30],H1: 42
2023.04.15 20:43:26.064    Expert maybeload [DJI30],H1: loaded successfully
  • 推测42是进程句柄而非错误码
  • 已尝试调整ShellExecute参数:使用java.exe全路径、javaw.exe、修改显示参数(SW_SHOWNORMAL、SW_SHOWDEFAULT等),均无改善
  • 手动通过CMD或双击可正常启动.jar文件并显示窗口,怀疑是MQL线程处理问题

解决方案

问题根源

  1. ShellExecute参数未正确使用:DLL中定义了Java全路径但未实际调用,而是直接传java.exe,MT4的工作目录不是Java安装目录,导致系统找不到可执行文件,进程启动后立即退出。
  2. 工作目录不匹配:MT4启动DLL时的工作目录是自身安装/数据目录,若Jar文件不在该目录下,Java无法找到目标文件。
  3. 字符串编码冲突:MQL字符串为ANSI编码,Delphi默认字符串为Unicode,参数传递时可能出现乱码,导致命令解析失败。

具体修复步骤

1. 修正DLL代码(兼容ANSI编码+明确路径)

library JarLauncher;

uses
    Windows, ShellAPI, SysUtils;

function LaunchJar(const AFileName: PAnsiChar; const AArguments: PAnsiChar): Integer; stdcall;
var
    JavaPath: AnsiString;
    CmdLine: AnsiString;
    WorkDir: AnsiString;
begin
    // 使用32位Java全路径
    JavaPath := 'C:\Program Files (x86)\Java\jre1.8.0_361\bin\java.exe';
    // 拼接命令行:传入Jar绝对路径
    CmdLine := '-Xmx1024M -Xms1024M -jar ' + AFileName;
    if AArguments <> '' then
        CmdLine := CmdLine + ' ' + AArguments;
    
    // 提取Jar文件所在目录作为工作目录
    WorkDir := ExtractFilePath(AFileName);
    // 使用ShellExecuteA确保ANSI编码兼容MQL
    Result := ShellExecuteA(
        0,
        nil,
        PAnsiChar(JavaPath),
        PAnsiChar(CmdLine),
        PAnsiChar(WorkDir),
        SW_SHOWNORMAL
    );
end;

exports
    LaunchJar;

begin
end.

2. 修正MQL代码(传入Jar绝对路径)

#import "JarLauncher.dll"
int LaunchJar(string AFileName, string AArguments);
#import

void OnInit()
{
   // 替换为你的Jar文件绝对路径
   string jarFile = "C:\\path\\to\\testpilot.jar";
   string arguments = "";
   
   int result = LaunchJar(jarFile, arguments);
   // ShellExecute返回值<=32表示错误
   if (result <= 32)
   {
      Print("Failed to launch JAR file! Error code: ", result);
   }
   else
   {
      Print("Launch succeeded, handle: ", result);
   }
   Sleep(9000);
}

3. 备选方案:改用CreateProcess直接启动进程

若ShellExecute仍有问题,使用CreateProcessA跳过Shell解析,更稳定:

library JarLauncher;

uses
    Windows, SysUtils;

function LaunchJar(const AFileName: PAnsiChar; const AArguments: PAnsiChar): Integer; stdcall;
var
    JavaPath: AnsiString;
    CmdLine: AnsiString;
    StartupInfo: TStartupInfoA;
    ProcessInfo: TProcessInformation;
    WorkDir: AnsiString;
begin
    Result := 0;
    JavaPath := 'C:\Program Files (x86)\Java\jre1.8.0_361\bin\java.exe';
    // 给路径加双引号,避免空格解析错误
    CmdLine := '"' + JavaPath + '" -Xmx1024M -Xms1024M -jar "' + AFileName + '"';
    if AArguments <> '' then
        CmdLine := CmdLine + ' ' + AArguments;
    
    WorkDir := ExtractFilePath(AFileName);
    ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
    StartupInfo.wShowWindow := SW_SHOWNORMAL;
    
    if CreateProcessA(
        nil,
        PAnsiChar(CmdLine),
        nil,
        nil,
        False,
        0,
        nil,
        PAnsiChar(WorkDir),
        StartupInfo,
        ProcessInfo
    ) then
    begin
        Result := Integer(ProcessInfo.hProcess);
        // 关闭多余句柄,避免资源泄漏
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);
    end
    else
    begin
        Result := GetLastError();
    end;
end;

exports
    LaunchJar;

begin
end.

验证步骤

  1. 重新编译DLL和Java Jar文件
  2. 确保Jar文件位于MQL代码指定的绝对路径下
  3. 启动MT4加载脚本,查看控制台输出及Java窗口是否正常弹出

内容的提问来源于stack exchange,提问作者Duke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:24:56