从 C# 调用 Delphi DLL 会产生意外结果

2023-11-22

我有一个不是我编写的 Delphi DLL,但需要从 C# ASP.NET 3.5 应用程序调用。这是我从开发人员那里得到的函数定义:

function CreateCode(SerialID : String; 
    StartDateOfYear, YearOfStartDate, YearOfEndDate, DatePeriod : Word; 
    CodeType,RecordNumber,StartHour,EndHour : Byte) : PChar;
    external 'CreateCodeDLL.dll';

这是我的 C# 代码:

[DllImport( "CreateCodeDLL.dll", 
    CallingConvention = CallingConvention.StdCall, 
    CharSet=CharSet.Ansi)]
public static extern IntPtr CreateCode( string SerialID,
                                        UInt16 StartDateOfYear,
                                        UInt16 YearOfStartDate,
                                        UInt16 YearOfEndDate,
                                        UInt16 DatePeriod,
                                        Byte CodeType,
                                        Byte RecordNumber,
                                        Byte StartHour,
                                        Byte EndHour);

最后,我调用这个方法:

//The Inputs 
String serialID = "92F00000B4FBE";
UInt16 StartDateOfYear = 20;
UInt16 YearOfStartDate = 2009;
UInt16 YearOfEndDate = 2009;
UInt16 DatePeriod = 7;
Byte CodeType = 1;
Byte RecordNumber = 0;
Byte StartHour = 15;
Byte EndHour = 14;            

// The DLL call
IntPtr codePtr = CodeGenerator.CreateCode(serialID, StartDateOfYear, 
                YearOfStartDate, YearOfEndDate, DatePeriod, CodeType, 
                RecordNumber, StartHour, EndHour);

// Take the pointer and extract the code in a string
String code = Marshal.PtrToStringAnsi(codePtr);  

每次我重新编译这个确切的代码并运行它时,它都会返回不同的值。预期值是由数字组成的 10 位代码。返回值实际上是12位数字。

最后一条重要信息是我有一个测试 .EXE,它有一个 GUI,允许我测试 DLL。使用 .EXE 的每个测试都会返回相同的 10 位数字(预期结果)。

因此,我必须相信我错误地声明了对 DLL 的调用。想法?


Delphi 使用所谓的fastcall默认调用约定。这意味着编译器尝试将参数传递给 CPU 寄存器中的函数,并且仅在参数多于可用寄存器时才使用堆栈。例如,Delphi 使用(EAX、EDX、ECX)作为函数的前三个参数。
在您的 C# 代码中,您实际上使用的是stdcall调用约定,指示编译器通过堆栈传递参数(以相反的顺序,即最后一个参数首先被压入)并让被调用者清理堆栈。
相比之下,cdeclC/C++ 编译器使用的调用强制调用者清理堆栈。
只需确保双方使用相同的调用约定即可。 Stdcall 最常用,因为它几乎可以在任何地方使用,并且每个编译器都支持(Win32 API 也使用此约定)。
注意fastcall无论如何,.NET 不支持。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 C# 调用 Delphi DLL 会产生意外结果 的相关文章

  • 将 new 与 decltype 一起使用

    T t T is an implementation detail t new T want to avoid naming T to allow for flexibility t new decltype t error cannot
  • Delphi 2010 控制闪烁

    我一直在从 XP 操作系统升级或迁移我们的软件 以便能够在 Windows 7 下编译和运行 我们的软件开始出现我们在 Windows XP 下没有注意到的问题 目前 我正在处理 TForm 上闪烁的用户定义控件 它似乎时不时地闪烁 但并非
  • 在路由mvc 4中添加公司名称

    我一直在尝试为 Facebook 等用户提供在 URL 中添加公司名称的选项 http localhost 50753 MyCompany Login 我尝试过不同的网址 但没有成功 routes MapRoute name Default
  • 在 Java 中创建 T 的新实例

    在C 中 我们可以定义一个泛型class A
  • 如何使用 SOAP 且不使用 WSE 在 .NET 中签署 Amazon Web 服务请求

    亚马逊产品广告 API 以前称为 Amazon Associates Web Service 或 Amazon AWS 实施了一项新规则 即自 2009 年 8 月 15 日起 向其发送的所有 Web 服务请求都必须经过签名 他们在其网站上
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • C# 开源 NMEA 解析器 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 C 开源 NMEA 解析器 嗯 我自己也不熟悉 但是一些快速搜索显示了一个代码项目 htt
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • Project Euler #8,我不明白我哪里出了问题[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在做项目欧拉第八题 https projecteuler net problem 8 其中我得到了这个大得离谱的数字 7316
  • 在 Delphi 中,我的 DLL 中是否必须分配函数的返回 pchar

    我有一个 DLL 其中有一个返回 pchar 的函数 以避免必须使用 borlndmm 我最初所做的是将字符串转换为 pchar 并返回 Result pChar SomeFuncThatReturnsString 但 90 的情况下我都能
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • 英文日期差异

    接近重复 如何计算相对时间 https stackoverflow com questions 11 how do i calculate relative time 如何在 C 中计算某人的年龄 https stackoverflow c
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 如何调试 .NET 运行时中的内部错误?

    我正在尝试调试一些处理大文件的工作 代码本身works 但 NET 运行时本身会报告零星错误 对于上下文 这里的处理是一个 1 5GB 文件 仅加载到内存中一次 在循环中处理和释放 故意尝试重现此否则不可预测的错误 我的测试片段基本上是 t
  • 如何在 winforms 应用程序的主屏幕显示之前显示欢迎屏幕?

    我想在应用程序启动时加载欢迎屏幕 然后用户单击欢迎屏幕上的按钮 然后关闭欢迎屏幕 最后显示主屏幕 static void Main startup method being called Application EnableVisualSt
  • DataContractSerializer 事件/委托字段问题

    在我的 WPF 应用程序中 我正在使用DataContractSerializer序列化对象 我发现它无法序列化具有事件或委托声明的类型 考虑以下失败的代码 Serializable public abstract class BaseCl
  • 为什么匹配模板类上的部分类模板特化与没有模板匹配的另一个部分特化不明确?

    这个问题可能很难用标题中的句子来描述 但这里有一个最小的例子 include

随机推荐

  • std::some-namespace::transform 有一天可以支持任何函子吗?

    std transform来自
  • 如何通过curl 使用 Nexus 的 REST API 从 Nexus 检索工件校验和?

    我正在尝试验证从 Nexus 下载的工件的校验和 我可以抓取该工件并下载它们并检查它们的 md5sum 或 sha1sum 但我需要根据 Nexus 的实际总和进行检查 以便我可以验证它们是否正确 这是我用来从 Nexus 获取文件的命令
  • 可腌制的图像对象

    如何从 PIL 图像对象创建可pickle 文件 以便可以将这些图像保存为单个 pickle 文件 然后上传到另一台计算机 例如运行 PIL 的服务器 并在那里取消pickle 您可以将 Image 对象转换为数据 然后可以对其进行 pic
  • Anaconda python、PIL 和 Imagingtk

    虽然这是一个相当不错的有记录的问题 我找不到解决办法 我无法导入 PIL 和 ImageTK 最小的例子 import Tkinter as tk from PIL import Image ImageTk root tk Tk image
  • GEE 中的负二项式

    对于实现 GEE 的 R 包 例如gee geepack 好像不包括负二项式族 我有两个问题 还有我不知道的其他 GEE R 软件包吗 如果没有 是否有一个简单的步骤来允许创建一个族 即提供链接功能 log mu 和方差函数 mu mu 2
  • 防止在 WiX 主要升级期间删除/安装服务 - 服务不停止

    我遇到了我想象的常见情况 但无法让事情完全正常进行 场景非常简单 我想对产品进行重大升级 而不更改服务设置 也不需要重新启动 在正常安装中 该服务应该安装并启动 卸载时 该服务应停止并被删除 升级时 应停止 而不是删除 服务 写入新文件 然
  • 在 Play 框架中使用 ElementCollection 时出现 LazyInitializationException

    我的应用程序模型集中有一个用户实体 定义如下 public class User extends Model private String name private byte sk Column columnDefinition BINAR
  • .htaccess 中的 RewriteRule 不起作用

    我目前在本地计算机上运行 Apache2 并安装了最新版本的 Ubuntu 我正在尝试使用 htaccess 文件进行基本的 URL 重写 文件 http localhost page php home 确实存在 而位置 doesnotex
  • 将 Select2 集成到 Angular2 应用程序中

    我正在尝试整合Select2进入Angular2我正在构建的应用程序 我设法得到select2正在运行 我的多个选择按预期进行了转换 我现在的问题是我应该如何获取选定的值以及我应该使用哪个事件进行绑定 我尝试绑定 change select
  • 将 Windows 7 屏幕键盘合并到 WPF 应用程序中

    Windows 7 有一个非常好的触摸屏屏幕键盘程序 控件 我有一个触摸屏应用程序 最初是为 XP 编写的 并将部署在 XP 上 是否可以将此键盘直接合并到我的应用程序中 而不是使用自定义控件 我找不到有关它的程序信息 因此任何链接都会非常
  • Laravel 队列作业未更新到最新代码

    我正在使用 laravel 队列作业发送带有 Excel 附件的电子邮件 很多时候 每当我更新任何代码更改时 它都不会考虑更新的代码 而是运行旧代码 我怎样才能防止这种情况发生 每次部署 Laravel 应用程序或进行任何代码更改时 您都应
  • 监控 Nexus 仓库

    有谁知道允许监控 mvn 工件部署到 nexus 存储库的 nexus 插件或 API 我的问题是 开发人员正在将各种 jar 上传到 Nexus 存储库 而我无法知道谁做了什么以及为什么 我如何对他们强制执行规则 以便他们在将任何 jar
  • 从同一源重新加载 元素

    我在 URL 中有一张图片http 192 168 1 53 html cam jpg 来自 Raspberry Pi 并且该图像变化非常快 来自相机 因此 我想在网站上使用一些 JavaScript 例如每秒重新加载该图像 我的 HTML
  • 如何使用SIMD来加速两个内存块的异或?

    我想尽快对两个内存块进行异或 如何使用SIMD来加速它 我的原始代码如下 void region xor w64 unsigned char r1 Region 1 unsigned char r2 Region 2 int nbytes
  • 序列化lua表的方法

    我可能错过了这一点 但是是否有一个内置方法可以将 lua 表序列化 反序列化为文本文件 反之亦然 我有两种方法可以在固定格式的 lua 表上执行此操作 例如 3 列数据 5 行 有没有办法在 lua 表上执行此操作随意的格式 举个例子 给定
  • 如何在 Google App Engine 模板系统中注册自定义过滤器?

    根据 Django 文档 我已经注册了我的过滤器 from google appengine ext webapp import template register template create template register reg
  • 如何在不使用 Vidalia 的情况下强制 Tor 使用新身份?

    我在用Tor在我的项目中 如何强制 Tor 使用我的程序中的新身份 打开与 Tor 服务控制端口的 telnet 连接并发送SIGNAL NEWNYM 我希望你可以使用任何 Delphi telnet 库 我的第一选择是Indy 确保你有最
  • 从finally块返回时Java的奇怪行为

    试试这段代码 为什么 getValueB 返回 1 而不是 2 毕竟 increment 函数被调用了两次 public class ReturningFromFinally public static int getValueA This
  • 每个用户仅允许一次会话

    我们有一个使用 struts2 spring 和 hibernate 开发的 Web 应用程序 该应用程序需要一个用户只能从一个浏览器登录的功能 假设用户 x 在 pc 1 浏览器 ff 上登录 那么他无法从任何其他地方登录 我尝试通过实现
  • 从 C# 调用 Delphi DLL 会产生意外结果

    我有一个不是我编写的 Delphi DLL 但需要从 C ASP NET 3 5 应用程序调用 这是我从开发人员那里得到的函数定义 function CreateCode SerialID String StartDateOfYear Ye