解决Delphi BPL包问题BPL不会加载但您已经重新编译(Windows VirtualStore文件系统问题)(Solving Delphi BPL Package problems where BPLs won't load but you've already recompiled (Windows VirtualStore filesystem issue))
我的一般问题是如何排除故障“无论我的清理和重新编译多少,我的BPL都不会加载,因为依赖关系不会消失。 更新你可能认为你有一个干净的重新编译的系统,但是由于反向奇迹是Windows及其文件系统虚拟化错误特征,所以你没有。
当我尝试将我的designtime包(在本例中命名为
dclFsTee.bpl
)dclFsTee.bpl
到我的Delphi IDE(它是快速报告4 teechart包装器组件包)时,它会抱怨:The program can't start because tee7100.bpl is missing from your computer. Try reinstalling ...
我的系统上没有任何DCP或DCU文件引用
tee7100.bpl
。 但很明显,有些事情是错的,我找不到问题。所有德尔福用户面临100个“不会编译或不会加载”BPL问题。 当被问及要做什么时,通用的限制是清理你的计算机。
然而,我现在花了几个小时清理我的电脑,当一切都编译文件时,显然必须有些东西隐藏在某处,因为我试图加载的BPL文件仍然需要加载一个版本的几天前我从这个系统中删除的TeeChart BPL,以及我能找到的每一条痕迹。
我删除的Delphi 2007中的TeeChart东西的痕迹包括$(BDS)\ Lib和$(BDS)\ Lib \ debug文件夹中的所有内容以及系统上的所有DCP和BPL文件夹。 每个TeeChart单元命名的dcu文件也不见了。
一旦你走到路的尽头,你接下来要做什么? (格式化硬盘,购买新电脑。)认真。 我认为我是一个聪明人,但我有一个1 TB的硬盘,一个运行到80多个文件夹的库路径,以及一个似乎组织良好的源代码存储库,但显然有些东西隐藏在我无法做到的地方找到它。
我有TeeChart标准2012,完整的源代码,据我所知,我的开发机器不再包含任何TeeChart BPL或DCP文件从德尔福附带的“tee chart tee7100.bpl”版本。
在向tee.inc文件写入{$ DEFINE x}声明之后,我运行了teechart附带的“recompile.exe”向导,该向导似乎只运行MSBuild并构建了包(源代码中有两个)分配)。
然而,无论如何,默默地,它似乎是隐式导入到其中一个包中的一个,它正在绘制一些尚未重建的过时文件,因此会尝试加载tee7100.bpl。 新的bpl名称是tee911.bpl。
我只提到它是一个在德尔福开发时遇到了几十次伤害的普遍世界的特定实例,而不是提出这个非常具体到快速的报告问题。
我只给出了快速报告的详细信息,以便您可以看到这实际上是Delphi IDE在处理组件源代码或程序包或一组程序包时遇到的一般问题的特定实例,它们具有相关性。 清理您的计算机,以便您的代码甚至可以构建起来可能会非常棘手。
所以这里是我的Delphi包到包依赖解决问题:
找到或追踪一些不再想要的BPL问题的隐式加载的最有效方法是什么,以便我的代码(构建和编译得很好!)实际上会加载到Delphi IDE中。 运行重新编译导致的BPL文件似乎正确链接到正确的DCP文件,并且不存在旧的/陈旧的DCP或DCU文件。 例如,新的DCP文件名是tee911.dcp。
你能以某种方式知道什么软件包实际上是陈旧的,什么是在.bpl链接时被静态读取和链接和导入? (我想也许像BPL文件的特殊MAP类文件?)
更新经过几个小时的战斗,并使用我所知道的每一个技巧,我意识到我没有检查由Windows 7中的文件虚拟化引起的一些
VirtualStore
相关问题 。这意味着Windows 7对于运行在它。 它给你另一个版本的文件,这不是你想要的。 这可能在几个方面是致命的; 一; 你重新编译一个BPL,但那不是加载的那个。 杀死我的BPL位于作为VirtualStore一部分的SysWow64文件夹中。 请注意,虚拟存储基本上使幻像文件出现,只有当你是一个特定的“低级privelege”程序,在Win7 / 64位上的Delphi 2007,显然是。 要删除当前用户帐户的SysWow64 VIRTUALSTORE文件夹中的BPL文件:del %HOMEPATH%\AppData\Local\VirtualStore\Windows\SysWow64\*.bpl
...有些日子我讨厌Windows架构。 无论如何,我不会把上面的答案作为答案,因为我想知道是否有人有更好的方法或任何提示或建议可能会帮助下一次。
My general question is how do you troubleshoot "My BPL won't load due to a dependency that just won't go away, no matter how much I clean up and recompile". Update You may think you have a clean recompiled system, but thanks to the inverse-miracle that is Windows and its file system virtualization mis-features, you haven't.
When I try to load my designtime package (in this case named
dclFsTee.bpl
) into my Delphi IDE (it's the fast report 4 teechart wrapper component package), it complains:The program can't start because tee7100.bpl is missing from your computer. Try reinstalling ...
That
tee7100.bpl
is not referenced on any DCP or DCU file on my system THAT I KNOW OF. But clearly, something is wrong, and I can't find the problem.All Delphi users face a hundred "won't compile or won't load" problems with BPLs. The universal refrain when asked what to do is to clean up your computer.
However, I've now spent hours cleaning up my computer, and while everything compiles file, clearly there must be something out of date hiding somewhere, because the resulting BPL file that I'm trying to load still wants to load a version of a TeeChart BPL that I removed from this system days ago, along with every trace I could find.
The traces of TeeChart stuff in Delphi 2007 that I removed include everything in the $(BDS)\Lib and $(BDS)\Lib\debug folder, and all DCP and BPL folders on the system. Also every TeeChart-unit-named dcu file is gone.
Once you've gotten to the end of the road, what do you try next? (Format the hard drive, buy new computer.) Seriously. I think I'm a smart guy, but I have a 1 tb hard drive, a library path that runs to 80+ folders, and a source code repository that seems to be well organized, but clearly something is hiding where I can't find it.
I have TeeChart Standard 2012, with full source code, and as far as I know, my development machine no longer contains any old TeeChart BPLs or DCP files from the "tee chart tee7100.bpl" version that ships with delphi.
I have run the "recompile.exe" wizard that comes with teechart, which appears to just run MSBuild and build the packages, after writing a {$DEFINE x} declaration to the tee.inc files (there are two of them in the source distribution).
However, somehow, silently it seems like one of the implicit imports into one of the packages is drawing in some stale file which has not been rebuilt, and which therefore tries to load the tee7100.bpl. The new bpl name is tee911.bpl.
Rather than ask the pretty-specific-to-fastreport question, I'm only mentioning it as a specific instance of a general world of hurt that I have faced dozens of times while developing in Delphi.
I'm only giving the fast-report details so you can see that this is in fact a specific instance of a general problem that one faces sometimes inside Delphi IDE when dealing with a component source code or package, or set of packages, with dependencies. Cleaning up your computer so that your code even builds can be tricky.
So here is my Delphi package-to-package-dependency-resolution question:
What is the most effective way to find or trace implicit-load-of-some-no-longer-wanted BPL-problems so that my code (which builds and compiles just fine!) will actually load into the Delphi IDE. The BPL file that results from running Recompile seems to be linking properly to the right DCP files, and no old/stale DCP or DCU files are present. The new DCP file name is tee911.dcp, for instance.
Can you get somehow, any idea of what package is actually stale, and what is being read and linked and imported statically when the .bpl links? (I'm thinking maybe like a special MAP-like file for BPL files?)
Update After many hours of fighting with this, and using every trick I know, I realized I hadn't checked for some
VirtualStore
related issues caused by file virtualization in Windows 7. That means that Windows 7 lies to the programs that run on top of it. It gives you another version of the file, that isn't the one you want. This can be deadly in several ways; One; You recompile a BPL but that's not the one that loads. The BPL that was killing me was in the SysWow64 folder that was part of the VirtualStore. Note that the virtualstore basically makes phantom files appear that are only there if you're a certain "low privelege" program, which Delphi 2007 on Win7/64 bit, apparently is. To remove BPL files in your SysWow64 VIRTUALSTORE folder for your current user account:del %HOMEPATH%\AppData\Local\VirtualStore\Windows\SysWow64\*.bpl
... Some days I just hate Windows architecture. Anyways, I'm not going to put the above as the answer, because I'd like to know if anyone has a better way or any tip or suggestion that might help next time.
原文:https://stackoverflow.com/questions/12161554
最满意答案
您需要将
AnotherMethod
传递给某个特定类型的一个委托,而是构造委托的一个委托。 我认为这只能使用反射或动态类型来完成:void Run () { AnotherMethod("something", (t, u) => GenericMethod(t, u)); } void GenericMethod<T, U> (T obj, U parm1) { Console.WriteLine("{0}, {1}", typeof(T).Name, typeof(U).Name); } void AnotherMethod(string parm1, Action<dynamic, dynamic> method) { method("test", 1); method(42, "hello world!"); method(1.2345, "etc."); }
请注意,
(t, u) => GenericMethod(t, u)
不能用GenericMethod
来替换。You need to pass into
AnotherMethod
not a single delegate of some specific type, but a thing which contructs delegates. I think this can only be done using reflection or dynamic types:void Run () { AnotherMethod("something", (t, u) => GenericMethod(t, u)); } void GenericMethod<T, U> (T obj, U parm1) { Console.WriteLine("{0}, {1}", typeof(T).Name, typeof(U).Name); } void AnotherMethod(string parm1, Action<dynamic, dynamic> method) { method("test", 1); method(42, "hello world!"); method(1.2345, "etc."); }
Note that
(t, u) => GenericMethod(t, u)
cannot be replaced with justGenericMethod
.
相关问答
更多-
您需要将AnotherMethod传递给某个特定类型的一个委托,而是构造委托的一个委托。 我认为这只能使用反射或动态类型来完成: void Run () { AnotherMethod("something", (t, u) => GenericMethod(t, u)); } void GenericMethod
(T obj, U parm1) { Console.WriteLine("{0}, {1}", typeof(T).Name, typeof(U).Name); ... -
C ++模板和.NET泛型只是看起来相同,但表现不同:.NET泛型需要在编译时完全可解析。 在您的示例中,这是不可能的。 您可以使用dynamic关键字为C ++模板获得类似的结果: public void setUniform1
(int loc, T value) { GL.Uniform1(loc, (dynamic)value); } 这会将重载决策推迟到运行时,此时实际知道value的类型。 但是,如果GL.Uniform1没有超出value的类型,它会产生异常的问题。 尽管如此,我 ... -
您不需要基类,只需指定一个必须是类(而不是结构)的约束。 这可以通过where TEntity : class来完成 类型参数的约束 where T : class :type参数必须是引用类型; 这也适用于任何类,接口,委托或数组类型。 修改代码 private IHttpActionResult GetData
(DbSet data) where TEntity : class You do not need a base class, you only have ... -
无法在具有泛型的方法中将集合类作为参数传递(Not able to pass collections classes as a parameter in a method with generic)[2022-11-17]
使用JVM? 对于Java 8,这是一个有效的代码,它工作正常。 HTH,Gal JVM used? For Java 8 this is a valid code and it works fine. HTH, Gal -
这将如何实现? 就个人而言,我只是摆脱你的通用方法。 无论如何,它只对两个类型参数有效 - 将其拆分为带有两个重载的重载方法: internal static double? RoundNullable(double? nullable, int decimals) { return nullable.HasValue ? Math.Round(nullable.Value, decimals) : (double?) null; } in ...
-
您不能通过传递运行时类型来编写泛型方法来运行。 泛型需要在编译时具有该类型。 您可能需要使用反射(请参阅费雷拉先生关于如何做到这一点的答案)。 You cannot code Generic methods to run by passing a runtime Type. Generics need to have the type at compile time. You may need to use reflection (see answer of mr. Ferreira that point ...
-
可能最好的方法是在Java 8中像Stream.map一样实现它,并提供您自己的接口(可能称为Mapper ,但为了在调用站点提供实现,您必须使用匿名内部类。 Lambdas更好。 它可能看起来像这样: public interface Mapper
{ U map(T t); } ListUtils会这样: public class ListUtils { public static List mapObjectToField(List elements, Map ... -
如何将实际方法作为参数传递给Java中的另一个方法?(How can you pass in an actual method as a parameter to another method in Java?)[2020-01-19]
直接在Java中没有一流的功能支持。 两种选择: 传递方法的名称,并使用反射来获取它 创建一个包含单个成员的类型,如下所示: public interface Function{ Out apply(In input); } 然后你可以使用匿名内部类,如下所示: joinOnMethod(", ", someList, new Function () { @Override public String apply(T inp ... -
将func从方法参数传递给LINQ方法(泛型)(Passing func from method parameter into a LINQ method (generic types))[2021-06-21]
在LINQ中,哪种方法(来自IEnumerable)将允许我将方法参数中的Func传递给LINQ查询? LinqToObjects的扩展方法挂在静态System.Linq.Enumerable类上。 鉴于您的Func签名,您可能需要Enumerable.Where重载。 IEnumerableEnumerable.Where (this IEnumerable source, Func filter) In LINQ, which method (from IEnumer ... -
您不需要重载该方法,因为Java会使用原始类型隐式执行此操作。
E[] toArray(List data) { 如果你打电话 List objs = ... Object[] array = toArray(objs); 如果你使用泛型,你会得到泛型 List strs = String[] array = toArray(objs); 你遇到的真正问题是没有办法实现toArray。 这是因为在运行时不知道泛型类型。 即你不能创建一个E数组,也不能将Object[]转换 ...