Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ visualc&x2B+;如何为Delphi导出x64 DLL函数_C++_Visual Studio_Dll_64 Bit - Fatal编程技术网

C++ visualc&x2B+;如何为Delphi导出x64 DLL函数

C++ visualc&x2B+;如何为Delphi导出x64 DLL函数,c++,visual-studio,dll,64-bit,C++,Visual Studio,Dll,64 Bit,我主要是一个Delphi开发人员,我一直在使用一个DLL包装器,它与Logitech的G15 etc api DLL接口,与键盘LCD屏幕交互 几年前,有人制作了这个包装器用于delphi,基本上是一个与Logitech库接口的DLL,并将函数导出到delphi。它一直工作得很好,但是它只有32位 我得到了包装器源代码,并试图将其编译为64位,但出现了一些问题。我将平台设置为64位,相应地更改了配置等(我认为),并将库路径指向Logitech 64bit.lib 导出似乎在那里,但当我尝试加载任

我主要是一个Delphi开发人员,我一直在使用一个DLL包装器,它与Logitech的G15 etc api DLL接口,与键盘LCD屏幕交互

几年前,有人制作了这个包装器用于delphi,基本上是一个与Logitech库接口的DLL,并将函数导出到delphi。它一直工作得很好,但是它只有32位

我得到了包装器源代码,并试图将其编译为64位,但出现了一些问题。我将平台设置为64位,相应地更改了配置等(我认为),并将库路径指向Logitech 64bit.lib

导出似乎在那里,但当我尝试加载任何带有GetProcAddress的文件时,我得到一个错误“找不到指定的模块”

怎么了

// lgLCDWrapper.DLL
//
// A Wrapper-DLL for Delphi and other compilers who cannot include the original
// lcLcd.Lib provided by Logitech. These functions are needed to communicate with
// the graphical LCD of an Logitech G15-Keyboard.
//
// Code by Olaf Stieleke, May 1st, 2007
// Compiler Visual C++ 2005 Express Edition
// Hereby dedicated to Open Source under GPL-License.
//

//Make sure to set additional Include-Path to lglcd.h (found in Logitech-SDK-Folders)
//Make sure to set additional Library-Path to lglcd.lib (found in Logitech-SDK-Folders)

#include "stdafx.h"
#include <lglcd.h>
#include "lgLcdWrapper.h"


BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call,LPVOID lpReserved)
{
    return TRUE;
}

DWORD _cdecl lgLcdInitWrap(void)
{
    return lgLcdInit();
}

DWORD _cdecl lgLcdDeInitWrap(void)
{
    return lgLcdDeInit();
}
DWORD _cdecl lgLcdConnectAWrap(lgLcdConnectContextA *ctx)
{
    return lgLcdConnectA(ctx);
}
DWORD _cdecl lgLcdDisconnectWrap(int connection)
{
    return lgLcdDisconnect(connection);
}
DWORD _cdecl lgLcdEnumerateWrap(int connection, int index, lgLcdDeviceDesc *description)
{
    return lgLcdEnumerate(connection,index,description);
}
DWORD _cdecl lgLcdOpenWrap(lgLcdOpenContext *ctx)
{
    return lgLcdOpen(ctx);
}
DWORD _cdecl lgLcdCloseWrap(int device)
{
    return lgLcdClose(device);
}
DWORD _cdecl lgLcdReadSoftButtonsWrap(int device, DWORD *buttons)
{
    return lgLcdReadSoftButtons(device,buttons);
}
DWORD _cdecl lgLcdUpdateBitmapWrap(int device, lgLcdBitmapHeader *bitmap, DWORD priority)
{
    return lgLcdUpdateBitmap(device,bitmap,priority);
}
DWORD _cdecl lgLcdSetAsLCDForegroundAppWrap(int device, int foregroundYesNoFlag)
{
    return lgLcdSetAsLCDForegroundApp(device,foregroundYesNoFlag);
}

stdafx.cpp

    #include "stdafx.h"
    // stdafx.h : Includedatei für Standardsystem-Includedateien
// oder häufig verwendete projektspezifische Includedateien,
// die nur in unregelmäßigen Abständen geändert werden.
//

#pragma once

// Ändern Sie folgende Definitionen für Plattformen, die älter als die unten angegebenen sind.
// In MSDN finden Sie die neuesten Informationen über die entsprechenden Werte für die unterschiedlichen Plattformen.
#ifndef WINVER              // Lassen Sie die Verwendung spezifischer Features von Windows XP oder später zu.
#define WINVER 0x0501       // Ändern Sie dies in den geeigneten Wert für andere Versionen von Windows.
#endif

#ifndef _WIN32_WINNT        // Lassen Sie die Verwendung spezifischer Features von Windows XP oder später zu.                   
#define _WIN32_WINNT 0x0501 // Ändern Sie dies in den geeigneten Wert für andere Versionen von Windows.
#endif                      

#ifndef _WIN32_WINDOWS      // Lassen Sie die Verwendung spezifischer Features von Windows 98 oder später zu.
#define _WIN32_WINDOWS 0x0410 // Ändern Sie dies in den geeigneten Wert für Windows Me oder höher.
#endif

#ifndef _WIN32_IE           // Lassen Sie die Verwendung spezifischer Features von IE 6.0 oder später zu.
#define _WIN32_IE 0x0600    // Ändern Sie dies in den geeigneten Wert für andere Versionen von IE.
#endif

#define WIN32_LEAN_AND_MEAN     // Selten verwendete Teile der Windows-Header nicht einbinden.
// Windows-Headerdateien:
#include <windows.h>
我收到一个错误“找不到指定的模块”

这不是GetProcAddress产生的错误,您可以从LoadLibrary()获得该错误。错误代码126。GetProcAddress失败,错误为127,“找不到指定的过程。”“。因此,请检查您的错误处理代码,它可能有错误。并三次检查是否为DLL使用了正确的路径名,以及是否正确部署了依赖DLL,如CRT DLL

唯一其他相关的技巧是应用于64位DLL中导出函数的名称修饰。您的客户机代码之前肯定使用了类似“_lgLcdInitWrap”的名称,前导下划线表示__cdecl调用约定生效。幸运的是,64位代码与调用约定无关,只有一种。因此,出口不再装饰,它将只是简单的“lgLcdInitWrap”。使用dumpbin.exe/exports或depends.exe之类的工具,您肯定会看到一些东西

我收到一个错误“找不到指定的模块”

这不是GetProcAddress产生的错误,您可以从LoadLibrary()获得该错误。错误代码126。GetProcAddress失败,错误为127,“找不到指定的过程。”“。因此,请检查您的错误处理代码,它可能有错误。并三次检查是否为DLL使用了正确的路径名,以及是否正确部署了依赖DLL,如CRT DLL


唯一其他相关的技巧是应用于64位DLL中导出函数的名称修饰。您的客户机代码之前肯定使用了类似“_lgLcdInitWrap”的名称,前导下划线表示__cdecl调用约定生效。幸运的是,64位代码与调用约定无关,只有一种。因此,出口不再装饰,它将只是简单的“lgLcdInitWrap”。使用dumpbin.exe/exports或depends.exe之类的工具,您肯定会看到一些东西。

发现了问题。当我在VS2010中添加x64平台时,它设置了2个设置,导致了整个问题:

项目选项>链接器>高级> -随机基址 -数据执行预防(DEP)

禁用这两个设置修复了它


找到了问题。当我在VS2010中添加x64平台时,它设置了2个设置,导致了整个问题:

项目选项>链接器>高级> -随机基址 -数据执行预防(DEP)

禁用这两个设置修复了它


我认为你应该在定义之前加上
extern“C”\uu declspec(dllexport)
;导出似乎存在,但GetProcAddress无法加载任何32位和64位进程使用不同的搜索路径和(某些)注册表项(在32位时工作正常)。例如,64位进程使用system32,而32位进程使用SysWOW64(在64位操作系统上)。32位进程无法加载64位DLL,反之亦然。这可能是问题的根源-请尝试使用ProcMon找出DLL的搜索位置。最有可能的情况是,它没有在你期望的地方搜索,或者你混合了32位和64位的可执行文件。不,应用程序是64位的,我把DLL放在同一个文件夹中。LoadLibrary工作正常,只是GetProcAddress返回“找不到指定的模块”,但根据依赖性Walkera,导出已正确存在。您是否绝对确定这是从GetProcAddress得到的错误,并且LoadLibrary确实成功了?GetProcAddress查找过程,而不是模块。如果确实是找不到的过程,则导出的函数可能会被破坏。在32位构建中是否使用了.def文件?我认为您应该在定义之前添加
extern“C”\uu declspec(dllexport)
;导出似乎存在,但GetProcAddress无法加载任何32位和64位进程使用不同的搜索路径和(某些)注册表项(在32位时工作正常)。例如,64位进程使用system32,而32位进程使用SysWOW64(在64位操作系统上)。32位进程无法加载64位DLL,反之亦然。这可能是问题的根源-请尝试使用ProcMon找出DLL的搜索位置。最有可能的情况是,它没有在你期望的地方搜索,或者你混合了32位和64位的可执行文件。不,应用程序是64位的,我把DLL放在同一个文件夹中。LoadLibrary工作正常,只是GetProcAddress返回“找不到指定的模块”,但根据依赖性Walkera,导出已正确存在。您是否绝对确定这是从GetProcAddress得到的错误,并且LoadLibrary确实成功了?GetProcAddress查找过程,而不是模块。如果确实是找不到的过程,则导出的函数可能会被破坏。在32位Buffer-Erm中是否使用了.DEF文件,错误是在GETPROCELATE之后出现的:(在末尾添加了主问题代码)第一步通过了,我得到了DLL的句柄,然后GETPROCELATE引发了错误。我回答了MSVC C++问题,不能帮助您解决Delphi问题。显然有问题,GetProcAddress无法生成关于模块的错误,它已经有了模块
    #include "stdafx.h"
    // stdafx.h : Includedatei für Standardsystem-Includedateien
// oder häufig verwendete projektspezifische Includedateien,
// die nur in unregelmäßigen Abständen geändert werden.
//

#pragma once

// Ändern Sie folgende Definitionen für Plattformen, die älter als die unten angegebenen sind.
// In MSDN finden Sie die neuesten Informationen über die entsprechenden Werte für die unterschiedlichen Plattformen.
#ifndef WINVER              // Lassen Sie die Verwendung spezifischer Features von Windows XP oder später zu.
#define WINVER 0x0501       // Ändern Sie dies in den geeigneten Wert für andere Versionen von Windows.
#endif

#ifndef _WIN32_WINNT        // Lassen Sie die Verwendung spezifischer Features von Windows XP oder später zu.                   
#define _WIN32_WINNT 0x0501 // Ändern Sie dies in den geeigneten Wert für andere Versionen von Windows.
#endif                      

#ifndef _WIN32_WINDOWS      // Lassen Sie die Verwendung spezifischer Features von Windows 98 oder später zu.
#define _WIN32_WINDOWS 0x0410 // Ändern Sie dies in den geeigneten Wert für Windows Me oder höher.
#endif

#ifndef _WIN32_IE           // Lassen Sie die Verwendung spezifischer Features von IE 6.0 oder später zu.
#define _WIN32_IE 0x0600    // Ändern Sie dies in den geeigneten Wert für andere Versionen von IE.
#endif

#define WIN32_LEAN_AND_MEAN     // Selten verwendete Teile der Windows-Header nicht einbinden.
// Windows-Headerdateien:
#include <windows.h>
DLLHandle := LoadLibrary('lgLcdWrapperX64.dll');
  if DLLHandle = 0 then Exit(False);

  @lgLcdInit       := GetProcAddress(dllHandle, 'lgLcdInitWrap');
  if (not Assigned(lgLcdInit)) then ShowMessage(SysErrorMessage(GetLastError));