我使用Delphi的Tethering Components来实现我的想法。除非您决定构建EXE,否则所有工作都非常出色。在重新构建之后启动时,我收到此错误:
这只发生在新构建之后。如果我再次编译应用程序,问题就会消失,一切正常。一旦我构建了应用程序,并且我调试了代码,它就会给我一个错误:
TetheringAppProfile := TTetheringAppProfile.Create(nil);
with TetheringAppProfile do
begin
Manager := TetheringManager; //This line
Text := 'AppTether';
end
为了尝试找到解决此问题的方法,我决定将我的代码移到一个程序包中,每次构建我的EXE时都不会重新编译。这个想法听起来很酷,但没有用,这让我感到困惑。我所做的是实现我在这里找到的想法:Advanced Dynamic Packages
它向您展示了如何使用您自己的自定义方法在代码中动态加载包。我用了第一个例子。我实现了一个包含我想要调用的所有方法的基础包。此包作为运行时包包含在内。然后我添加了另一个包含表单的包,该表单需要基本包,但是单独分发。我的思维过程是,如果我能够构建主要的EXE并且其他代码保持不变,那么这个问题不应该发生。但是,不,当我重建我的主要exe时,出于某种原因在那条线上,我仍然得到那个错误。如果我重新构建在代码中动态加载的一个包,并重新运行主exe而不做任何进一步的操作,它就可以工作。为什么呢?
我一直在寻找这个错误,但是我没有通过XE6中的Tethering Components找到解决此问题的人。
这是callstack:
exception class : EInsufficientRtti
exception message : Insufficient RTTI available to support this operation.
main thread ($4d60):
004c17a2 +000e JAM.exe System.Rtti CheckCodeAddress
004ce740 +0508 JAM.exe System.Rtti TRttiInstanceMethodEx.DispatchInvoke
004d7f5c +0044 JAM.exe System.Rtti TRttiMethod.Invoke
010d4701 +017d JAM.exe IPPeerAPI TIPPeerFactory.CreatePeer
012258c9 +0051 JAM.exe System.Tether.NetworkAdapter TTetheringNetworkAdapter.Create
0122592f +0007 JAM.exe System.Tether.NetworkAdapter TTetheringNetworkAdapter.CreateInstance
011ffa6d +0019 JAM.exe System.Tether.Manager TTetheringAdapters.GetAdapterInstance
011fb98e +004a JAM.exe System.Tether.Manager TTetheringManager.AutoCreateAdapters
011fdce2 +0016 JAM.exe System.Tether.Manager TTetheringManager.RegisterProfile
011ff0d7 +0023 JAM.exe System.Tether.Manager TTetheringProfile.SetManager
0126f62a +004e JAM.exe uTetherPackage 47 +11 TTetherPackage.CreateTetherComponents
01270283 +003f JAM.exe uTetherings 146 +6 TTetherings.CreateTetherings
01942794 +1210 JAM.exe uMain 1031 +321 TfrmMain.FormCreate
00686f2d +0031 JAM.exe Vcl.Forms 3745 +3 TCustomForm.DoCreate
00686b31 +0011 JAM.exe Vcl.Forms 3628 +1 TCustomForm.AfterConstruction
00409bd9 +001d JAM.exe System 492 +0 @AfterConstruction
00686ae3 +019b JAM.exe Vcl.Forms 3618 +35 TCustomForm.Create
00691546 +0076 JAM.exe Vcl.Forms 10470 +13 TApplication.CreateForm
01990d87 +0307 JAM.exe JAM 1469 +113 initialization
76d07c02 +0022 KERNEL32.DLL BaseThreadInitThunk
thread $643c:
76621129 +000 KERNELBASE.dll WaitForMultipleObjectsEx
76ffde8d +15d user32.dll MsgWaitForMultipleObjectsEx
76ffdbda +01a user32.dll MsgWaitForMultipleObjects
004aaa15 +00d JAM.exe madExcept CallThreadProcSafe
004aaa7a +032 JAM.exe madExcept ThreadExceptFrame
76d07c02 +022 KERNEL32.DLL BaseThreadInitThunk
>> created by main thread ($4d60) at:
6d8ae04a +000 gdiplus.dll
thread $587c (TDMSThread):
76612cc1 +b1 KERNELBASE.dll WaitForSingleObjectEx
76612bfd +0d KERNELBASE.dll WaitForSingleObject
010adb07 +1b JAM.exe uSignalFlag 54 +3 TSignalFlag.WaitForSignal
010ba90d +49 JAM.exe uDMSWriter 1672 +7 TDMSThread.Execute
004aab2f +2b JAM.exe madExcept HookedTThreadExecute
0052a371 +49 JAM.exe System.Classes ThreadProc
0040b230 +28 JAM.exe System 492 +0 ThreadWrapper
004aaa15 +0d JAM.exe madExcept CallThreadProcSafe
当我尝试进入产生错误的行时,它会将System.Generics.Collections带到此方法:
function TEnumerable<T>.ToArrayImpl(Count: Integer): TArray<T>;
var
x: T;
begin
// We assume our caller has passed correct Count
SetLength(Result, Count);
Count := 0;
for x in Self do
begin
Result[Count] := x;
Inc(Count);
end;
end;
Here is the stack track for that part:
Vcl.Themes.{System.Generics.Collections}TEnumerable<System.string>.ToArrayImpl(1)
:01201989 {System.Generics.Collections}TDictionary<System.string,System.Tether.Manager.TTetheringAdapterClass>.TKeyCollection.ToArray + $15
:011fdcd3 TTetheringManager.RegisterProfile + $1B
uMain.TfrmMain.FormCreate($82F69A0)
Vcl.Forms.TCustomForm.DoCreate
Vcl.Forms.TCustomForm.AfterConstruction
:00686b37 TCustomForm.AfterConstruction + $17
Vcl.Forms.TCustomForm.Create(???)
Vcl.Forms.TApplication.CreateForm(???,(no value))
JAM.JAM
:76d07c04 KERNEL32.BaseThreadInitThunk + 0x24
:776eab8f ntdll.RtlInitializeExceptionChain + 0x8f
:776eab5a ntdll.RtlInitializeExceptionChain + 0x5a
当我走出ToArrayImpl方法时,它会给出异常......
知道如何解决这个问题吗?