[英]E2276 error when attempting to export to .DLL a function overloaded across units
我一直在將有用的例程收集到實用程序單元中,然后將其編譯為.DLL和.DCU,因此我可以選擇哪種方法可以方便地訪問這些例程。
例如,我編寫了自己的Lowcase ,它作用於[寬]字符或[寬]字符串,以實現明顯的功能,而Embarcadero卻沒有實現。
類似地,我擴展了Max和Min以查找數字數組的Max / Min。
在某些情況下,我實際上只是為現有函數提供了一個別名,例如
function LowCase
(const st : ANSIstring
) : ANSIstring;
stdcall;
begin
result := ansilowercase(st);
end;
它將通過以下方式導出到DLL
exports LowCase
(const st : ANSIstring
) name 'lowcaseansistr';
到現在為止還挺好。
我最近發現
var
v_uint64 : uint64;
v_uint64 := $FFFFFFFFFFFFFFFF;
writeln('v_uint64=',inttostr(v_uint64));
v_uint64 := $7FFFFFFFFFFFFFFF;
writeln('v_uint64=',inttostr(v_uint64));
在第一個實例(-1)中產生了不正確的結果-實際上,無論MSB設置在哪里,但是在第二個MSB清除的情況下都可以。
因此,我發現uinttostr
並將此標准功能替換為inttostr
解決了該問題。
在ISTM中,如果我可以再次簡單地執行別名技巧,那將更加方便,所以我嘗試了(實現)
function inttostr
(p_nb_int : uint64
) : string;
stdcall;
begin
result := uinttostr(p_nb_int);
end;
(接口)
function inttostr
(p_nb_int : uint64
) : string;
overload;
stdcall;
運作得很愉快,但是實施了
exports inttostr
(p_nb_int : uint64
) name 'uinttostr64';
在項目中生成的E2276 Identifier 'IntToStr' cannot be exported
。 E2276似乎與local directive
,顯然是由local;
調用的local;
在聲明中-但在EMBT在System.Sysutils.pas中提供的源中,聲明為
function IntToStr(Value: Integer): string; overload;
function IntToStr(Value: Int64): string; overload;
沒有local;
在望!
所以-我很困惑。 我該如何解決? (XE2)
這是一個測試程序:
program countparamsshort;
{$APPTYPE CONSOLE}
{$R *.res}
uses
dxutypes,
// dxumethods,
system.math,windows,vcl.Graphics,classes,System.SysUtils;
//{$I C:\delphi\dxu.inc}
var
v_int64 : int64 ; // -2^63..2^63-1
v_uint64 : uint64; // 0..2^64-1
procedure showv;
begin
writeln('v_int64= ',inttostr(v_int64));
writeln('v_uint64=',inttostr(v_uint64));
end;
begin
writeln('min values');
v_int64 := -214748364999;
v_uint64 := 0;
showv;
writeln('max values');
v_int64 := $FFFFFFFFFFFFFFFF;
v_uint64 := $FFFFFFFFFFFFFFFF;
showv;
writeln('max 63-bit values');
v_int64 := $7FFFFFFFFFFFFFFF;
v_uint64 := $7FFFFFFFFFFFFFFF;
showv;
// writeln(inttostr(max(10,3)),' & ',inttostr(max([1,12,7,9,11,4])));
writeln('procedure finished');
readln;
end.
使用.dcu dxumethods並按原樣運行,並包括文件C:\\ delphi \\ dxu.inc注釋掉將調用inttostr
的system.math實現並生成報告
min values
v_int64= -214748364999
v_uint64=0
max values
v_int64= -1
v_uint64=-1
max 63-bit values
v_int64= 9223372036854775807
v_uint64=9223372036854775807
procedure finished
對於v_uint64
這是不正確的。 為uint64
調用uinttostr
可以解決問題,但要記住要這樣做。
從dxumethods元素中刪除注釋意味着包括我的inttostr
版本-實際上執行uinttostr
。 結果是:
min values
v_int64= -214748364999
v_uint64=0
max values
v_int64= -1
v_uint64=18446744073709551615
max 63-bit values
v_int64= 9223372036854775807
v_uint64=9223372036854775807
10 & 12
procedure finished
現在可以正確顯示v_uint64
的值。 這意味着我可以使用inttostr
而可以忘記所有有關uinttostr
,因此我不必坐在這里弄清楚什么時候應該使用哪個。 我已經解決了一次,現在編譯器可以在將來完成工作。
我還取消了對MAX
調用的注釋,該調用使用相同的方法來查找數組的max
-這意味着我可以忘記有關maxintvalue和maxvalue的所有信息(它會調用這些例程),但是我可以再次只需使用max
無論是傳統版本還是關於數組的相同概念。 當一個例程可以執行時,不要用三個例程(另外三個用於MIN等效項)使頭腦混亂。
最后,重新注釋dxumethods並取消注釋包含文件,其中包含如下行
function inttostr
(p_nb_int : uint64
) : string;
overload;
stdcall;
external 'dxuproject.dll' name 'uinttostr64';
產生的結果相同,這一次是從.DLL開始的-關鍵是在構造.DLL時限定函數名,否則您會E2276
錯誤。
現在-為什么發生這種情況,當圍繞MAX/MIN
進行的相似處理不會使編譯器感到困惑時,我將留給理論學家-它與似乎是Kylix宿醉的“本地”聲明有什么關系-嗯,這就是在眾神AFAICS的腿上(或可能是失誤)。
無論如何-好的結果; 問題解決了。 季節的問候...
也許當涉及到重載函數和名稱重整時, Delphi編譯器無法通過Uint64
參數告訴Int64
。 因此,請嘗試精確地指定要導出的功能,而無需依賴自動解析。
exports UnitName.FunctionName(Params);
我不太了解您的總體目標。 唯一可以導入此類功能的是使用與DLL相同的編譯器構建的Delphi代碼。 該代碼可以直接調用UIntToStr
。
而且您似乎也正在重新實現RTL已經具有的功能。 例如, AnsiStrings
單元將為8位文本提供大小寫轉換功能。 在Math
,將為浮點值數組找到MinValue/MaxValue
,為整數數組MinIntValue/MaxIntValue
。 在我看來,好像您是在重新發明輪子。
就是說,以您的問題為中心,這里是如何導出函數的方法:
library Project1;
uses
SysUtils;
exports
UIntToStr(Value: UInt64) name 'uinttostr64';
begin
end.
這將從SysUtils
導出函數,因此使用register
調用約定。 當然這對您沒有問題,因為您只能從Delphi調用該函數。
如果您急於導出IntToStr
,則應使用標准單元名稱。 例如,假設函數在Unit1
聲明,那么您應該編寫:
exports
Unit1.IntToStr(Value: UInt64) name 'uinttostr64';
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.