gpt4 book ai didi

c++ - 将数据从 Delphi DLL 传递到 C++ 应用程序

转载 作者:行者123 更新时间:2023-11-28 03:31:28 26 4
gpt4 key购买 nike

我有一个用 Delphi 编写的 DLL,它应该确定一些值,然后将结果传递回调用 DLL 的 C++ 应用程序。

要传递回 C++ 应用程序的数据是一组四个整数值(但将来也可能有字符串值)。

为此,我需要将这些整数值声明为在调用应用程序和 DLL 之间共享。

在 C++ 应用程序端,我可以这样做(根据 http://msdn.microsoft.com/en-us/library/h90dkhs0%28v=vs.80%29.aspx ):

#pragma data_seg(".SHARED")

int value1;
int value2;
// ...
int valueN;
#pragma data_seg()

我如何在 Delphi 2009 中做同样的事情(声明 value1-N 将存储在共享内存中)?

更新,2012 年 9 月 18 日:我决定使用命名管道来实现注入(inject)的 DLL 与外部世界的通信。

但在我可以使用命名管道之前,我需要解决以下问题。

目前,流程是这样的:

1) 将 DLL 注入(inject)遗留应用程序。

2) DLL 从遗留应用程序中提取一些数据。

3) DLL被卸载。

我需要修改它,让它像这样工作:

1) 将 DLL 注入(inject)遗留应用程序。2) DLL 开始一个循环,如

bool running = true;
while (running)
{
command = receiveCommandFromInvokingApp();
if ("GET_COORDINATES".equals(command))
{
// Read coordinates of some cell in the grid
// Then communicate it via some channel to the outside world
}
else if ("READ_CELL_VALUE")
{
// Read value of some cell in the grid
// Then communicate it via some channel to the outside world
}
else if ("EXIT")
{
// Close the communication channel
// Perform cleanup work
running = false;
}

// Sleep for, say, 500 milliseconds in order to avoid 100 % CPU usage
}

receiveCommandFromInvokingApp 读取从调用应用程序(从命名管道或任何其他合适的 channel )发送的下一个命令。

3) 当调用应用程序发送 EXIT 命令时,DLL 停止循环。

假设我有以下 DLL 代码:

procedure DllMain(reason: integer) ;
begin
if reason = DLL_PROCESS_DETACH then
OutputDebugString('DLL PROCESS DETACH')
else if reason = DLL_THREAD_ATTACH then
OutputDebugString('DLL THREAD ATTACH')
else if reason = DLL_THREAD_DETACH then
OutputDebugString('DLL THREAD DETACH')
else if reason = DLL_PROCESS_ATTACH then
OutputDebugString('DLL_PROCESS_ATTACH')
end;
end; (*DllMain*)

循环应该放在哪里(在什么分支)?

用它代替 OutputDebugString('DLL THREAD ATTACH') 是否明智?

2012 年 9 月 19 日更新:

我的系统设计发生了变化,现在我通过命名管道将数据从 Delphi DLL 发送到 C# 应用程序。

德尔福代码:

打开命名管道:

function OpenNamedPipe() : THandle;
var
hPipe : THandle;
name : string;
connectResult : LongBool;
begin
name := '\\.\pipe\delphi-to-cpp';
hPipe := CreateNamedPipe(PChar(name),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_NOWAIT,
PIPE_UNLIMITED_INSTANCES,
4096 ,
4096 ,
4096 ,
NIL);
if (hPipe = INVALID_HANDLE_VALUE) then
begin
OutputDebugString(PChar('Invalid pipe handle: ' + IntToStr(GetLastError)));
OutputDebugString(PChar(SysErrorMessage(GetLastError)));
end;


OutputDebugString(PChar('OpenNamedPipe, 1'));
connectResult := ConnectNamedPipe(hPipe, NIL);
OutputDebugString(PChar('connectResult: ' + BoolToStr(connectResult)));
OutputDebugString(PChar(SysErrorMessage(GetLastError)));

OpenNamedPipe := hPipe;
end;

发送消息:

procedure SendMessageToNamedPipe(hPipe:THandle; msg:string);
var
dwWrite : DWORD;
lpNumberOfBytesWritten : LongBool;
MsgLength: DWORD;
MsgW : PWideChar;
begin
MsgW := PWideChar(msg);
MsgLength := lstrlenW(MsgW) * SizeOf(WideChar);
lpNumberOfBytesWritten := WriteFile(hPipe, MsgW, MsgLength, dwWrite, NIL);

if not lpNumberOfBytesWritten then
begin
OutputDebugString(PChar('Sending error: ' + SysErrorMessage(GetLastError)));
end
else
begin
OutputDebugString(PChar('Message sent, dwWrite: ' + IntToStr(dwWrite)));
end;
end;

C# 代码,应该读取 Delphi 应用程序发送的数据:

  NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", "delphi-to-cpp",
PipeDirection.InOut);

new NamedPipeClientStream(".", "delphi-to-cpp",
PipeDirection.InOut);

Debug.WriteLine("Before pipeClient.Connect");

this.IsRunning = true;


pipeClient.Connect(5000);
StreamReader reader = new StreamReader(pipeClient, Encoding.Unicode);

while (this.IsRunning && pipeClient.IsConnected)
{
string message = reader.ReadLine();

Thread.Sleep(250);
}
reader.Close();

此代码不起作用 - reader.ReadLine(); 不返回任何内容。

如果我尝试按字节方式将数据读入 char[] 缓冲区,则该缓冲区在读取结束时包含垃圾。

请注意,C# 应用程序实际上正在接收某些内容,我只是不知道如何从流中提取文本。

我应该如何修改我的代码(Delphi、C# 或两者),以便 Delphi 应用程序发送的文本正确到达 C# 端?

最佳答案

Delphi 工具链没有内置该功能。

为了在 Delphi 中做类似的事情,您需要使用内存映射文件 API,或其他一些进程间通信 (IPC) 机制,例如管道、套接字、Windows 消息等。

或者,您可以简单地从您的 Delphi DLL 加载 C++ DLL。 C++ DLL 可以访问共享数据,您的 Delphi DLL 可以调用 C++ DLL 中读取和写入共享数据的函数。然而,共享数据确实非常不适合这项任务。使用IPC更合适。

您在问题中没有说清楚的是,这里有两个过程。因此需要 IPC。

关于c++ - 将数据从 Delphi DLL 传递到 C++ 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12457888/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com