我有一个需要在WinXP和Vista64上运行的应用程序.我的程序需要QueryFullProcessImageName()才能在Vista上运行,但不能在XP上运行.
我尝试通过kernel32.dll加载QueryFullProcessImageName()(而不是静态链接),以便在WinXP和Vista上运行相同的可执行文件.加载它的代码是:
//only gets called on vista
bool LoadQueryFullProcessImageName()
{
HMODULE hDLL = LoadLibrary("kernel32.dll");
if (!hDLL) return(0);
//Now use pointer to get access to functions defined in DLL
fpQueryFullProcessImageName = (LPQueryFullProcessImageName)GetProcAddress(hDLL, "QueryFullProcessImageNameA"); //ANSI version
if (!fpQueryFullProcessImageName)
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
typedef是
typedef WINBASEAPI
BOOL (*LPQueryFullProcessImageName)(
__in HANDLE hProcess,
__in DWORD dwFlags,
__out_ecount_part(*lpdwSize, *lpdwSize) LPSTR lpExeName,
__inout PDWORD lpdwSize
);
Run Code Online (Sandbox Code Playgroud)
不幸的是,当取消引用函数指针时,我在Vista上遇到运行时错误:
运行时检查失败#0 - ESP的值未在函数调用中正确保存.这通常是调用使用一个调用约定声明的函数和使用不同调用约定声明的函数指针的结果.
typedef直接来自.h文件,所以我无法理解为什么它会搞乱.有帮助吗?我尝试了很多变种,但没有运气.
我有两个问题;我相信第一个更容易的问题必须在第二个之前解决,所以我在这里只坚持那个。
首先,概述:我有一个使用 USB 端口的硬件设备,并且有一个自定义 DLL 可以与它通信。我正在使用 VB.net 从 C++ 升级。自定义 DLL 有许多函数,我已经能够为除一个之外的所有函数进行编程,使用 IntPtr 和 Marshalling 函数进行更简单的 DLL 调用;最后一个,这将是我的第二个问题/帖子,给我带来了问题。它是一种回调类型操作,并使用 TYPEDEF 定义。
所以,第一个问题:我如何转换
typedef void (WINAPI *MyFunctPtr)(unsigned char*,int, LPVOID)
Run Code Online (Sandbox Code Playgroud)
进入VB.net?我理解(我认为)这是定义一个名为 MyFunctPtr 的指针,它接受三个参数,并且是 VOID 的别名,这意味着它不会返回任何内容。这是正确的,我如何在 VB.net 中使用它?
typedef 的用法如下:
AddHandler(MyPtrType func, LPVOID pParam);
Run Code Online (Sandbox Code Playgroud)
其中 AddHandler 是 DLL 调用(这将是我的第二个问题/帖子的主题,以及所需的 DECLARE 语句)。
为了追求这个主题,我查看了许多论坛和问答式讨论,但似乎没有一个专门解决这个问题(至少,我的无知不能说)。我确实在这个论坛中发现了一个与同一问题非常接近的主题(“在 .NET 中使用 C 回调函数”),但我知道的不够多;我什至不明白答案,更别提问题了!
正如我所指出的,这个问题还有第二部分:
1.此代码旨在通过 USB 与外部硬件设备进行通信。我成功地使用了许多其他函数,使用 DLL 调用和带 INTPTR 的封送处理。
2.但是这段代码需要的功能有些不同。从本质上讲,涉及四个方面的努力:
a) 通过执行 DLL 调用来响应“GoButton”点击,该调用将 CallBack 函数注册到外部设备(这是一个 DLL 调用,当然,传递对 CallBack 函数的引用。这会告诉外部硬件向何处发送它是发生适当事件时的数据)并产生第二个线程。
b) 作为新产生的第二个线程,通过执行 DLL 调用来响应,该调用实际上告诉外部硬件“OK,开始响应事件,并将数据发送到 CallBack”
c) 在第一个/原始线程中,通过执行 …
我编写了一个C DLL和一些C#代码来测试包含这个DLL并从中执行函数.我对这个过程并不太熟悉,每当从C#源代码调用DLL函数时,我都会收到PInvokeStackImbalance异常.代码如下(我已经评论了大多数代码来隔离这个问题):
C#包含代码:
using System;
using System.Runtime.InteropServices;
using System.IO;
namespace TestConsoleGrids
{
class Program
{
[DllImport("LibNonthreaded.dll", EntryPoint = "process")]
public unsafe static extern void process( long high, long low);
static void Main(string[] args)
{
System.Console.WriteLine("Starting program for 3x3 grid");
process( (long)0, (long)0 );
System.Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
C++ DLL函数代码
extern "C" __declspec(dllexport) void process( long high, long low );
void process( long high, long low )
{
// All code commented out
}
Run Code Online (Sandbox Code Playgroud)
Visual Studio生成了dllmain代码(我不明白这个构造,所以我包括它)
// dllmain.cpp : Defines the …Run Code Online (Sandbox Code Playgroud) 我在一些代码中遇到了一个typedef,它是这样的:
typedef void (NE_API *NeWindowProcCallback)(void* hWnd, NEuint uMsgId, NEuint wParam, NEuint64 lParam);
Run Code Online (Sandbox Code Playgroud)
但是,我不熟悉这种语法.谁有人解释这个?
另外,如果我跳到NE_API的声明,我发现:
# define NE_API __stdcall
Run Code Online (Sandbox Code Playgroud)
我认为这可能与答案有关,对此的解释也将非常感激.谢谢.
我MathFuncsDll.dll从https://msdn.microsoft.com/de-de/library/ms235636.aspx创建了没有问题的.我也可以在不同的C++项目中使用数学函数而不会出现问题.
现在我想在Excel VBA中使用这些功能.我试过了:
Public Declare Function DLL_Import_Add Lib "C:\Users\User\Desktop\MathFuncsDll.dll" Alias "Add" (ByVal a As Double, ByVal b As Double) As Double
Sub test()
MsgBox DLL_Import_Add(2.1, 3.3)
End Sub
Run Code Online (Sandbox Code Playgroud)
但是我收到了一个Run-time error '453'无法找到的DLL入口点.
我该如何解决这个问题?
MathFuncsDll.h:
// MathFuncsDll.h
#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport)
#else
#define MATHFUNCSDLL_API __declspec(dllimport)
#endif
namespace MathFuncs
{
// This class is exported from the MathFuncsDll.dll
class MyMathFuncs
{
public:
// Returns a + b
static MATHFUNCSDLL_API double Add(double a, double b);
// Returns …Run Code Online (Sandbox Code Playgroud)