从Delphi应用程序调用外部函数(C ++)时访问冲突(Access violation when calling external function (C++) from Delphi appli

编程入门 行业动态 更新时间:2024-10-28 17:21:56
从Delphi应用程序调用外部函数(C ++)时访问冲突(Access violation when calling external function (C++) from Delphi application)

我有一个用C ++编写的外部DLL。 下面的片断声明了一个结构类型和一个函数,它被赋予一个指针,它填充了这种类型的变量:

enum LimitType { NoLimit, PotLimit, FixedLimit }; struct SScraperState { char title[512]; unsigned int card_common[5]; unsigned int card_player[10][2]; unsigned int card_player_for_display[2]; bool dealer[10]; bool sitting_out[10]; CString seated[10]; CString active[10]; CString name[10]; double balance[10]; bool name_good_scrape[10]; bool balance_good_scrape[10]; double bet[10]; double pot[10]; CString button_state[10]; CString i86X_button_state[10]; CString i86_button_state; CString button_label[10]; double sblind; double bblind; double bbet; double ante; LimitType limit; double handnumber; bool istournament; }; extern "C" { SCRAPER_API int ScraperScrape(HWND hwnd, SScraperState *state); }

我在Delphi应用程序中声明了一个类似的类型,并调用上述函数:

interface type LimitType = (NoLimit, PotLimit, FixedLimit); SScraperState = record title: Array [0..511] of Char; card_common: Array [0..4] of Word; card_player: Array [0..9, 0..1] of Word; card_player_for_display: Array [0..1] of Word; dealer: Array [0..9] of Boolean; sitting_out: Array [0..9] of Boolean; seated: Array [0..9] of String; active: Array [0..9] of String; name: Array [0..9] of String; balance: Array [0..9] of Double; name_good_scrape: Array [0..9] of Boolean; balance_good_scrape: Array [0..9] of Boolean; bet: Array [0..9] of Double; pot: Array [0..9] of Double; button_state: Array [0..9] of String; i86X_button_state: Array [0..9] of String; i86_button_state: String; button_label: Array [0..9] of String; sblind: Double; bblind: Double; bbet: Double; ante: Double; limit: LimitType; handnumber: Double; istournament: Boolean; end; pSScraperState = ^SScraperState; function ScraperScrape(hWnd: HWND; State: pSScraperState): Integer; cdecl; external 'Scraper.dll'; implementation var CurState: SScraperState; pCurState: pSScraperState; if ScraperScrape(hWnd, pCurState) = 0 then ...

当函数被调用时,我得到调试器异常通知:

Project ...引发异常类EAccessViolation,并在消息'模块'Scraper.dll'中的地址10103F68发生访问冲突。 阅读地址FFFFFFFC'。 进程停止。

从同一个DLL导出的其他函数工作正常,所以我的猜测是我在类型声明中犯了一个错误。 任何提示将高度赞赏,因为我死在这一点上。

I've an external DLL written in C++. The piece below declares a struct type and a function, which, being given a pointer, fills a variable of this type:

enum LimitType { NoLimit, PotLimit, FixedLimit }; struct SScraperState { char title[512]; unsigned int card_common[5]; unsigned int card_player[10][2]; unsigned int card_player_for_display[2]; bool dealer[10]; bool sitting_out[10]; CString seated[10]; CString active[10]; CString name[10]; double balance[10]; bool name_good_scrape[10]; bool balance_good_scrape[10]; double bet[10]; double pot[10]; CString button_state[10]; CString i86X_button_state[10]; CString i86_button_state; CString button_label[10]; double sblind; double bblind; double bbet; double ante; LimitType limit; double handnumber; bool istournament; }; extern "C" { SCRAPER_API int ScraperScrape(HWND hwnd, SScraperState *state); }

I declare a similar type in my Delphi application and call the above function:

interface type LimitType = (NoLimit, PotLimit, FixedLimit); SScraperState = record title: Array [0..511] of Char; card_common: Array [0..4] of Word; card_player: Array [0..9, 0..1] of Word; card_player_for_display: Array [0..1] of Word; dealer: Array [0..9] of Boolean; sitting_out: Array [0..9] of Boolean; seated: Array [0..9] of String; active: Array [0..9] of String; name: Array [0..9] of String; balance: Array [0..9] of Double; name_good_scrape: Array [0..9] of Boolean; balance_good_scrape: Array [0..9] of Boolean; bet: Array [0..9] of Double; pot: Array [0..9] of Double; button_state: Array [0..9] of String; i86X_button_state: Array [0..9] of String; i86_button_state: String; button_label: Array [0..9] of String; sblind: Double; bblind: Double; bbet: Double; ante: Double; limit: LimitType; handnumber: Double; istournament: Boolean; end; pSScraperState = ^SScraperState; function ScraperScrape(hWnd: HWND; State: pSScraperState): Integer; cdecl; external 'Scraper.dll'; implementation var CurState: SScraperState; pCurState: pSScraperState; if ScraperScrape(hWnd, pCurState) = 0 then ...

When the function is called I get Debugger Exception Notification:

Project ... raised exception class EAccessViolation with message 'Access violation at address 10103F68 in module 'Scraper.dll'. Read of address FFFFFFFC'. Process stopped.

Other functions exported from the same DLL work fine, so my guess is I made a mistake in the type declaration. Any tips will be highly appreciated, as I'm dead stuck at this point.

最满意答案

C ++ CString和Delphi String是不兼容类型的主要问题ID。

如果你想以这种方式传递数据,你应该使用固定长度的字符数组或C样式空字符串(Delphi中的PChar)。

C ++会是这样的:

char Dealer[100][10];

如果错误,请编辑 - 自从我编写C代码以来,这已经很多年了

德尔福

Dealer : packed array[0..9, 0..99] of char;

要么

type TDealer = packed array[0..99] of char; ... Dealer : arry[0..9] of TDealer;

或者如果使用C字符串(API代码中的TCHAR)

Dealer: array[0..9] of PAnsiChar; // or PWideChar if source is UCS-16

还要注意在Delphi 2009中String,Char(因此PChar)从单字节变为双字节(UCS 16)。

其他数据类型也可能不同,例如在Delphi中,Word是16位,但在C ++中可能不同。 如果可能,请使用Windows API中常见的特定类型,例如USHORT而不是“unsigned int”和Word

The main problem id that C++ CString and Delphi String are incompatible types.

If you want to pass data in this manner, you should use either fixed length character arrays or C-Style null terminated strings (PChar in Delphi).

C++ would be something like:

char Dealer[100][10];

Please edit if wrong - it been many years since I done any C coding

Delphi

Dealer : packed array[0..9, 0..99] of char;

or

type TDealer = packed array[0..99] of char; ... Dealer : arry[0..9] of TDealer;

or if using C-string (TCHAR in API code)

Dealer: array[0..9] of PAnsiChar; // or PWideChar if source is UCS-16

Also note that String, Char (and hence PChar) changed from single byte to double byte (UCS 16) in Delphi 2009.

Other data types may be different as well e.g. In Delphi Word is 16bit, but may be different in C++. If possible use specific types that are common in the Windows API, such as USHORT instead of "unsigned int" and Word

更多推荐

本文发布于:2023-07-26 05:16:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1271392.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:应用程序   函数   冲突   Access   Delphi

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!