I'm experimenting with reconfiguring my application to make heaving use of packages. Both I and another developer running a similar experiment are running into a bit of trouble when linking using several different packages. We're probably both doing something wrong, but goodness knows what :)
我正在尝试重新配置我的应用程序,以便大量使用包。我和另一个运行类似实验的开发人员在使用几个不同的包链接时遇到了一点麻烦。我们可能都做错了什么,但天晓得:
The situation is this:
情况是这样的:
- The first package,
PackageA.bpl
, contains C++ classFooA
. The class is declared with thePACKAGE
directive. - 第一个包,PackageA。bpl,包含c++类FooA。类是用包指令声明的。
-
The second package,
PackageB.bpl
, contains a class inheriting fromFooA
, calledFooB
. It includesFooB.h
, and the package is built using runtime packages, and links toPackageA
by adding a reference toPackageA.bpi
.第二个包,PackageB。bpl包含一个继承自FooA的类,名为FooB。它包括FooB。h,该包使用运行时包构建,并通过向PackageA.bpi添加引用来链接到PackageA。
-
When building
PackageB
, it compiles fine but linking fails with a number of unresolved externals, the first few of which are:在构建PackageB时,它可以很好地编译,但是连接失败了,因为有许多未解决的外部因素,其中的前几个是:
[ILINK32 Error] Error: Unresolved external '__tpdsc__ FooA' referenced from C:\blah\FooB.OBJ
- 错误:未解析的外部“__tpdsc__ FooA”,引用自C:\blah\ foobo . obj
[ILINK32 Error] Error: Unresolved external 'FooA::' referenced from C:\blah\FooB.OBJ
- 错误:未解析的外部“FooA::”,引用自C:\blah\ foobj
[ILINK32 Error] Error: Unresolved external '__fastcall FooA::~FooA()' referenced from blah\FooB.OBJ
- 错误:未解析的外部“__fastcall FooA:::~FooA()”,引用自blah\ foobo . obj
etc.
等。
Running TDump on PackageA.bpl
shows:
运行TDump PackageA。底保说明:
Exports from PackageA.bpl
14 exported name(s), 14 export addresse(s). Ordinal base is 1.
Sorted by Name:
RVA Ord. Hint Name
-------- ---- ---- ----
00002A0C 8 0000 __tpdsc__ FooA
00002AD8 10 0001 __linkproc__ FooA::Finalize
00002AC8 9 0002 __linkproc__ FooA::Initialize
00002E4C 12 0003 __linkproc__ PackageA::Finalize
00002E3C 11 0004 __linkproc__ PackageA::Initialize
00006510 14 0007 FooA::
00002860 5 0008 FooA::FooA(FooA&)
000027E4 4 0009 FooA::FooA()
00002770 3 000A __fastcall FooA::~FooA()
000028DC 6 000B __fastcall FooA::Method1() const
000028F4 7 000C __fastcall FooA::Method2() const
00001375 2 000D Finalize
00001368 1 000E Initialize
0000610C 13 000F ___CPPdebugHook
So the class definitely seems to be exported and available to link. I can see entries for the specific things ILink32 says it's looking for and not finding. Running TDump on the BPI file shows similar entries.
因此,这个类显然是导出的,并且可以链接。我可以看到ILink32说它正在寻找而没有找到的具体东西的条目。在BPI文件上运行TDump会显示类似的条目。
Other info
The class does descend from TObject, though originally before refactoring into packages it was a normal C++ class. (More detail below. It seems "safer" using VCL-style classes when trying to solve problems with a very Delphi-ish thing like this anyway. Changing this only changes the order of unresolved externals to first not find Method1
and Method2
, then others.)
这个类确实是从TObject派生出来的,尽管在将其重构为包之前,它是一个普通的c++类。(更详细的研究。使用vcl样式的类来解决类似这样的问题似乎“更安全”。改变这一点只会改变未解决的外部因素的顺序,使其首先发现Method1和Method2,然后是其他的。
Declaration for FooA
:
FooA宣言:
class PACKAGE FooA: public TObject {
public:
FooA();
virtual __fastcall ~FooA();
FooA(const FooA&);
virtual __fastcall long Method1() const;
virtual __fastcall long Method2() const;
};
and FooB
:
和FooB:
class FooB: public FooA {
public:
FooB();
virtual __fastcall ~FooB();
... other methods...
};
All methods definitely are implemented in the .cpp files, so it's not not finding them because they don't exist! The .cpp files also contain #pragma package(smart_init)
near the top, under the includes.
所有方法都是在.cpp文件中实现的,所以不会找到它们,因为它们不存在!cpp文件还包含在include下的顶部附近的#pragma包(smart_init)。
Questions that might help...
- Are packages reliable using C++, or are they only useable with Delphi code?
- 使用c++包是可靠的,还是只能使用Delphi代码?
- Is linking to the first package by adding a reference to its BPI correct - is that how you're supposed to do it? I could use a LIB but it seems to make the second package much larger, and I suspect it's statically linking in the contents of the first.
- 通过添加对其BPI的引用来链接到第一个包是正确的吗?我可以使用LIB,但它似乎使第二个包更大,我怀疑它在第一个包的内容中是静态链接。
- Can we use the
PACKAGE
directive only onTObject
-derived classes? There is no compiler warning using it on standard C++ classes. - 我们可以只在tobject派生类上使用包指令吗?在标准c++类中,不存在使用它的编译器警告。
- Is splitting code into packages the best way to achieve the goal of isolating code and communicating through defined layers / interfaces? I've been investigating this path because it seems to be the C++Builder / Delphi Way, and if it worked it looks attractive. But are there better alternatives?
- 将代码分割成包是实现隔离代码和通过定义的层/接口进行通信的最佳方式吗?我一直在研究这条路径,因为它似乎是c++ Builder / Delphi的方法,如果行得通的话,看起来很有吸引力。但是有更好的替代方案吗?
- I'm very new to using packages and have only known about them through using components before. Any general words of advice would be great!
- 我对使用包非常陌生,以前只通过使用组件了解它们。任何建议都是很好的!
We're using C++Builder 2010. I've fabricated the class and method names in the above code examples, but other than that the details are exactly what we're seeing.
我们使用c++ Builder 2010。我在上面的代码示例中编造了类和方法名,但除此之外,细节正是我们所看到的。
3 个解决方案
#1
9
Unresolved external
The unresolved external in your case, seems to be because the compiler is unable to find the path to the package data. You should find out if:
在您的情况中,未解决的外部似乎是因为编译器无法找到包数据的路径。你应该弄清楚:
- The path exists in the compiler search path list.
- 路径存在于编译器搜索路径列表中。
- The package exists in the default package directory.
- 包存在于默认的包目录中。
If one of them is true then the path isn't the problem. However as Riho also mentions this is the most likely cause for the problem. The Embarcadero documentation wiki states the following about the unresolved external error:
如果其中一个是真的,那么路径不是问题。然而,Riho也提到这是最可能导致问题的原因。Embarcadero文档wiki对未解决的外部错误做了如下说明:
The named symbol is referenced in the given module but is not defined anywhere in the set of object files and libraries included in the link. Check to make sure the symbol is spelled correctly.
命名符号在给定的模块中被引用,但是在链接中包含的对象文件和库集中没有定义。检查确认符号拼写正确。
You will usually see this error from the linker for C or C++ symbols if any of the following occur:
如果出现以下任何错误,您通常会在链接器中看到C或c++符号的错误:
- You did not properly match a symbol’s declarations of
__pascal
and__cdecl
types in different source files.- 在不同的源文件中,您没有正确匹配符号的__pascal和__cdecl类型声明。
- You have omitted the name of an object file your program needs. You need to manually add all required packages to the Requires list.
- 您已经省略了程序需要的对象文件的名称。您需要手动将所有必需的包添加到需求列表中。
- You did not link in the emulation library.
- 您没有在模拟库中链接。
If you are linking C++ code with C modules, you might have forgotten to wrap C external declarations in extern “C”.
如果您正在将c++代码与C模块链接,那么您可能忘记了在extern“C”中包装C外部声明。
You could also have a case mismatch between two symbols.
您还可以在两个符号之间出现大小写不匹配。
Source: Unresolved external 'symbol' referenced from 'module'.
来源:未解析的外部“符号”来自“模块”。
Since it seems from the - although altered class names - it is not the case of a misspelling. You also state that you have added the package to the requires list so we rule out this as well. Since you are not linking to C modules we can omit that part as well. So it points to problems with the directory.
因为它看起来从-虽然改变了类名-它不是拼写错误的情况。您还声明您已经将包添加到需求列表中,因此我们也排除了这一点。由于您没有链接到C模块,所以我们也可以省略这一部分。它指向目录的问题。
About the other questions
Your questions are all really interesting and many of the questions are questions I my self has been looking for answers for when I started developing packages and components for C++ Builder.
您的问题都很有趣,很多问题都是我自己在为c++ Builder开发包和组件时一直在寻找的答案。
Are packages reliable using C++?
Packages are a fine solution to use for C++ Builder, Both C++ Builder is built to support packages and the Pascal written VCL framework. This means that certain implementations are different in C++ Builder than other compilers. This is a necessity to keep the language compatible with its Delphi sibling. For this reason you can use packages in C++ Builder almost as easily as if using Delphi.
对于c++ Builder来说,包是一个很好的解决方案,c++ Builder都是为支持包而构建的,Pascal编写的VCL框架也是如此。这意味着在c++ Builder中,某些实现与其他编译器不同。这是保持语言与Delphi语言兼容的必要条件。出于这个原因,您可以在c++ Builder中使用包,就像使用Delphi一样简单。
Is linking to the first package by adding a reference to its BPI correct?
To start with the second part of your question here, using a lib file makes your package larger simply because it is using static linking - so your guess is correct. Now back to the first part of the question, linking to a package is fine by adding a reference to its BPI. But you do need to make sure that the path variable has been set correctly as Riho suggests in his answer.
从问题的第二部分开始,使用lib文件使包更大,因为它使用静态链接—所以您的猜测是正确的。现在回到问题的第一部分,通过向包的BPI添加引用来链接包是可以的。但您确实需要确保路径变量被正确地设置,就像Riho在他的回答中所建议的那样。
Personally I always make sure to my packages to the proper directories in your users folder, the location of this is depending on your Delphi version and operating system version. As far as I recall it is under the Document and Settings\all users\shared documents\Rad studio(version number)\Packages but I could be mistaken about that.
就我个人而言,我总是确保我的包到您的用户文件夹中的正确目录,这取决于您的Delphi版本和操作系统版本。据我回忆,它是在“文档和设置”(Document and Settings)下,所有用户共享的文档\Rad studio(version number)\ package,但是我可能会弄错。
Can we use the PACKAGE
directive only on TObject
-derived classes?
The PACKAGE
macro is resolved into __declspec(package)
, you can compare it to __declspec(dllexport)
. The difference between these is that package is used when declared in a package, and dllexport is used when declared in a DLL. There is a topic about this on the official embarcadero forums titled __declspec(package) vs __declspec(dllexport). The author of the original post, also asks your exact question about this, but unfortunately that part of the question is unanswered.
包宏被解析为__declspec(PACKAGE),您可以将它与__declspec(dllexport)进行比较。它们之间的区别是,在包中声明时使用包,在DLL中声明时使用dllexport。在官方的embarcadero论坛上有一个名为__declspec(package)和__declspec(dllexport)的主题。原帖的作者也问了你确切的问题,但不幸的是,这部分问题没有得到解答。
I have a theory however, and I must emphasize that it is nothing more than a theory. Remy Lebeau writes as a response to the question in the forum post:
然而,我有一个理论,我必须强调,它只不过是一个理论。Remy Lebeau在论坛发帖回应了这个问题:
__declspec(dllexport) can be used for plain functions, data variables, and non-VCL classes, and can be used in plain DLLs. __declspec(package) is used for VCL components, and can only be used with packages.
__declspec(dllexport)可以用于普通函数、数据变量和非vcl类,也可以用于普通dll。__declspec(package)用于VCL组件,只能与包一起使用。
So from reading his response it seems to me that package is simply exporting the class, just like dllexport does. And since dllexport as far as I can read from his response is to be used in plain DLLs only you have to use the package for exporting (even) non VCL classes from a package.
因此,从他的回复中,我觉得这个包只是在导出类,就像dllexport所做的那样。而且,就我所知,dllexport的响应只能在普通dll中使用,所以您必须使用包从包中导出(甚至)非VCL类。
What is interesting about all this, is that a package is essentially a DLL as far as I recall, but I must admit I can't find or remember the source of that information so take with a grain of salt.
有趣的是,在我的记忆中,包本质上是一个DLL,但我必须承认我找不到或记不起这些信息的来源,所以我还是不信。
Is splitting code into packages the best way to achieve the goal of isolating code?
Packages have some very prominent strengths when creating reusable components for the VCL. Obviously using packages limits the user to use either C++Builder or Delphi, but for components written to take advantage of the VCL framework it's an excellent choice. Properly written packages can ease the reusability of components, and I believe it is the preferred method of distributing components for the VCL.
在为VCL创建可重用组件时,包有一些非常突出的优点。显然,使用包限制了用户使用c++ Builder或Delphi,但是对于使用VCL框架编写的组件来说,这是一个很好的选择。正确编写的包可以简化组件的重用性,我认为这是为VCL分发组件的首选方法。
However if your code does not take advantage of the VCL framework in any way, I would consider using an ordinary library, either static or dynamic, simply to create a more cross compiler friendly approach.
但是,如果您的代码没有以任何方式利用VCL框架,我将考虑使用一个普通的库(静态的或动态的)来创建一个更友好的跨编译器方法。
Whether there are any better approach to isolating your code, really depends on the project you are working on. I like to keep code that communicates through use of VCL classes in packages, but code that does not require use of any VCL classes in regular libraries. Keep in mind though that you can easily use VCL classes in a DLL but you need to handle special cases if you choose to export functions with VCL String classes as parameters or return values.
是否有更好的方法来隔离您的代码,这取决于您正在进行的项目。我喜欢保留通过在包中使用VCL类进行通信的代码,但是不需要在常规库中使用任何VCL类的代码。不过请记住,您可以在DLL中轻松地使用VCL类,但是如果您选择使用VCL字符串类作为参数或返回值来导出函数,则需要处理特殊情况。
Any general words of advice?
I'm not the most experienced developer of packages myself, but I have found that disabling runtime linking often solves a lot of my problems, while it is somewhat trivial to fix any problems for your own code, you can often run into 3rd party components that have trouble dealing with this. Having said that, I'm not a fan of distributing my packages along with my application as is required in this case. But to be honest that is a matter of taste.
我不是最有经验的开发人员自己的包,但是我发现禁用运行时链接通常解决我的很多问题,虽然有点琐碎的解决任何问题为你自己的代码,你可以经常遇到很难处理这种第三方组件。话虽如此,我并不喜欢随应用程序一起分发包。但说实话,这是一个品味问题。
Personally I found it difficult to find some proper answers to many of my questions, when I started creating components and packages. The official helpfile is not the most informative on the matter, but looking through the VCL source code, will often give you the best answer to your question. Besides there is a few other websites that can provide help, many of the sites are targeting Delphi though, but this you have to get used to though.
就我个人而言,当我开始创建组件和包时,我发现很难找到正确的答案来回答我的许多问题。官方的帮助文件并不是最能提供信息的,但是查看VCL源代码,通常会给你最好的答案。除了有一些其他的网站可以提供帮助之外,很多网站都是针对Delphi的,但是你必须习惯这一点。
Delphi Wikia has some good articles about creating components, in particular Creating Components and Creating Packages There is also BCB Journal which is one of the few C++ Builder specific sites, it has some fine articles and an acceptable forum. The Delphi pages at About.com is also a good source of information, I've found lots of good hints and nice to knows there, in particular: Creating Custom Delphi Components - Inside and Out.
Delphi Wikia有一些关于创建组件的好文章,特别是创建组件和创建包的文章,还有BCB Journal,它是少数几个c++ Builder的特定站点之一,它有一些很好的文章和一个可以接受的论坛。在About.com网站上的Delphi页面也是一个很好的信息来源,我发现了很多很好的提示和很好的了解,特别是:创建自定义的Delphi组件——从内部到外部。
#2
2
Maybe stupid question, but are your BPI/BPL files in correct path to be found by linker? I created once an app in BCB5 that used several linked packages, but don't remember if there was anything special in making them.
也许是愚蠢的问题,但是您的BPI/BPL文件是否正确地由链接器找到?我曾经在BCB5中创建过一个应用程序,它使用了几个链接包,但不记得它们是否有什么特别之处。
#3
1
For me #pragma package(smart_init,weak) in the cpp file solved the problem. See also http://flylib.com/books/en/3.264.1.27/1/ The cpp->obj file gets staticly linked without influencing anything else.
对于我来说cpp文件中的#pragma包(smart_init,弱项)解决了这个问题。参见http://flylib.com/books/en/3.264.1.27/1/ cpp->obj文件得到静态链接,不影响任何其他内容。
#1
9
Unresolved external
The unresolved external in your case, seems to be because the compiler is unable to find the path to the package data. You should find out if:
在您的情况中,未解决的外部似乎是因为编译器无法找到包数据的路径。你应该弄清楚:
- The path exists in the compiler search path list.
- 路径存在于编译器搜索路径列表中。
- The package exists in the default package directory.
- 包存在于默认的包目录中。
If one of them is true then the path isn't the problem. However as Riho also mentions this is the most likely cause for the problem. The Embarcadero documentation wiki states the following about the unresolved external error:
如果其中一个是真的,那么路径不是问题。然而,Riho也提到这是最可能导致问题的原因。Embarcadero文档wiki对未解决的外部错误做了如下说明:
The named symbol is referenced in the given module but is not defined anywhere in the set of object files and libraries included in the link. Check to make sure the symbol is spelled correctly.
命名符号在给定的模块中被引用,但是在链接中包含的对象文件和库集中没有定义。检查确认符号拼写正确。
You will usually see this error from the linker for C or C++ symbols if any of the following occur:
如果出现以下任何错误,您通常会在链接器中看到C或c++符号的错误:
- You did not properly match a symbol’s declarations of
__pascal
and__cdecl
types in different source files.- 在不同的源文件中,您没有正确匹配符号的__pascal和__cdecl类型声明。
- You have omitted the name of an object file your program needs. You need to manually add all required packages to the Requires list.
- 您已经省略了程序需要的对象文件的名称。您需要手动将所有必需的包添加到需求列表中。
- You did not link in the emulation library.
- 您没有在模拟库中链接。
If you are linking C++ code with C modules, you might have forgotten to wrap C external declarations in extern “C”.
如果您正在将c++代码与C模块链接,那么您可能忘记了在extern“C”中包装C外部声明。
You could also have a case mismatch between two symbols.
您还可以在两个符号之间出现大小写不匹配。
Source: Unresolved external 'symbol' referenced from 'module'.
来源:未解析的外部“符号”来自“模块”。
Since it seems from the - although altered class names - it is not the case of a misspelling. You also state that you have added the package to the requires list so we rule out this as well. Since you are not linking to C modules we can omit that part as well. So it points to problems with the directory.
因为它看起来从-虽然改变了类名-它不是拼写错误的情况。您还声明您已经将包添加到需求列表中,因此我们也排除了这一点。由于您没有链接到C模块,所以我们也可以省略这一部分。它指向目录的问题。
About the other questions
Your questions are all really interesting and many of the questions are questions I my self has been looking for answers for when I started developing packages and components for C++ Builder.
您的问题都很有趣,很多问题都是我自己在为c++ Builder开发包和组件时一直在寻找的答案。
Are packages reliable using C++?
Packages are a fine solution to use for C++ Builder, Both C++ Builder is built to support packages and the Pascal written VCL framework. This means that certain implementations are different in C++ Builder than other compilers. This is a necessity to keep the language compatible with its Delphi sibling. For this reason you can use packages in C++ Builder almost as easily as if using Delphi.
对于c++ Builder来说,包是一个很好的解决方案,c++ Builder都是为支持包而构建的,Pascal编写的VCL框架也是如此。这意味着在c++ Builder中,某些实现与其他编译器不同。这是保持语言与Delphi语言兼容的必要条件。出于这个原因,您可以在c++ Builder中使用包,就像使用Delphi一样简单。
Is linking to the first package by adding a reference to its BPI correct?
To start with the second part of your question here, using a lib file makes your package larger simply because it is using static linking - so your guess is correct. Now back to the first part of the question, linking to a package is fine by adding a reference to its BPI. But you do need to make sure that the path variable has been set correctly as Riho suggests in his answer.
从问题的第二部分开始,使用lib文件使包更大,因为它使用静态链接—所以您的猜测是正确的。现在回到问题的第一部分,通过向包的BPI添加引用来链接包是可以的。但您确实需要确保路径变量被正确地设置,就像Riho在他的回答中所建议的那样。
Personally I always make sure to my packages to the proper directories in your users folder, the location of this is depending on your Delphi version and operating system version. As far as I recall it is under the Document and Settings\all users\shared documents\Rad studio(version number)\Packages but I could be mistaken about that.
就我个人而言,我总是确保我的包到您的用户文件夹中的正确目录,这取决于您的Delphi版本和操作系统版本。据我回忆,它是在“文档和设置”(Document and Settings)下,所有用户共享的文档\Rad studio(version number)\ package,但是我可能会弄错。
Can we use the PACKAGE
directive only on TObject
-derived classes?
The PACKAGE
macro is resolved into __declspec(package)
, you can compare it to __declspec(dllexport)
. The difference between these is that package is used when declared in a package, and dllexport is used when declared in a DLL. There is a topic about this on the official embarcadero forums titled __declspec(package) vs __declspec(dllexport). The author of the original post, also asks your exact question about this, but unfortunately that part of the question is unanswered.
包宏被解析为__declspec(PACKAGE),您可以将它与__declspec(dllexport)进行比较。它们之间的区别是,在包中声明时使用包,在DLL中声明时使用dllexport。在官方的embarcadero论坛上有一个名为__declspec(package)和__declspec(dllexport)的主题。原帖的作者也问了你确切的问题,但不幸的是,这部分问题没有得到解答。
I have a theory however, and I must emphasize that it is nothing more than a theory. Remy Lebeau writes as a response to the question in the forum post:
然而,我有一个理论,我必须强调,它只不过是一个理论。Remy Lebeau在论坛发帖回应了这个问题:
__declspec(dllexport) can be used for plain functions, data variables, and non-VCL classes, and can be used in plain DLLs. __declspec(package) is used for VCL components, and can only be used with packages.
__declspec(dllexport)可以用于普通函数、数据变量和非vcl类,也可以用于普通dll。__declspec(package)用于VCL组件,只能与包一起使用。
So from reading his response it seems to me that package is simply exporting the class, just like dllexport does. And since dllexport as far as I can read from his response is to be used in plain DLLs only you have to use the package for exporting (even) non VCL classes from a package.
因此,从他的回复中,我觉得这个包只是在导出类,就像dllexport所做的那样。而且,就我所知,dllexport的响应只能在普通dll中使用,所以您必须使用包从包中导出(甚至)非VCL类。
What is interesting about all this, is that a package is essentially a DLL as far as I recall, but I must admit I can't find or remember the source of that information so take with a grain of salt.
有趣的是,在我的记忆中,包本质上是一个DLL,但我必须承认我找不到或记不起这些信息的来源,所以我还是不信。
Is splitting code into packages the best way to achieve the goal of isolating code?
Packages have some very prominent strengths when creating reusable components for the VCL. Obviously using packages limits the user to use either C++Builder or Delphi, but for components written to take advantage of the VCL framework it's an excellent choice. Properly written packages can ease the reusability of components, and I believe it is the preferred method of distributing components for the VCL.
在为VCL创建可重用组件时,包有一些非常突出的优点。显然,使用包限制了用户使用c++ Builder或Delphi,但是对于使用VCL框架编写的组件来说,这是一个很好的选择。正确编写的包可以简化组件的重用性,我认为这是为VCL分发组件的首选方法。
However if your code does not take advantage of the VCL framework in any way, I would consider using an ordinary library, either static or dynamic, simply to create a more cross compiler friendly approach.
但是,如果您的代码没有以任何方式利用VCL框架,我将考虑使用一个普通的库(静态的或动态的)来创建一个更友好的跨编译器方法。
Whether there are any better approach to isolating your code, really depends on the project you are working on. I like to keep code that communicates through use of VCL classes in packages, but code that does not require use of any VCL classes in regular libraries. Keep in mind though that you can easily use VCL classes in a DLL but you need to handle special cases if you choose to export functions with VCL String classes as parameters or return values.
是否有更好的方法来隔离您的代码,这取决于您正在进行的项目。我喜欢保留通过在包中使用VCL类进行通信的代码,但是不需要在常规库中使用任何VCL类的代码。不过请记住,您可以在DLL中轻松地使用VCL类,但是如果您选择使用VCL字符串类作为参数或返回值来导出函数,则需要处理特殊情况。
Any general words of advice?
I'm not the most experienced developer of packages myself, but I have found that disabling runtime linking often solves a lot of my problems, while it is somewhat trivial to fix any problems for your own code, you can often run into 3rd party components that have trouble dealing with this. Having said that, I'm not a fan of distributing my packages along with my application as is required in this case. But to be honest that is a matter of taste.
我不是最有经验的开发人员自己的包,但是我发现禁用运行时链接通常解决我的很多问题,虽然有点琐碎的解决任何问题为你自己的代码,你可以经常遇到很难处理这种第三方组件。话虽如此,我并不喜欢随应用程序一起分发包。但说实话,这是一个品味问题。
Personally I found it difficult to find some proper answers to many of my questions, when I started creating components and packages. The official helpfile is not the most informative on the matter, but looking through the VCL source code, will often give you the best answer to your question. Besides there is a few other websites that can provide help, many of the sites are targeting Delphi though, but this you have to get used to though.
就我个人而言,当我开始创建组件和包时,我发现很难找到正确的答案来回答我的许多问题。官方的帮助文件并不是最能提供信息的,但是查看VCL源代码,通常会给你最好的答案。除了有一些其他的网站可以提供帮助之外,很多网站都是针对Delphi的,但是你必须习惯这一点。
Delphi Wikia has some good articles about creating components, in particular Creating Components and Creating Packages There is also BCB Journal which is one of the few C++ Builder specific sites, it has some fine articles and an acceptable forum. The Delphi pages at About.com is also a good source of information, I've found lots of good hints and nice to knows there, in particular: Creating Custom Delphi Components - Inside and Out.
Delphi Wikia有一些关于创建组件的好文章,特别是创建组件和创建包的文章,还有BCB Journal,它是少数几个c++ Builder的特定站点之一,它有一些很好的文章和一个可以接受的论坛。在About.com网站上的Delphi页面也是一个很好的信息来源,我发现了很多很好的提示和很好的了解,特别是:创建自定义的Delphi组件——从内部到外部。
#2
2
Maybe stupid question, but are your BPI/BPL files in correct path to be found by linker? I created once an app in BCB5 that used several linked packages, but don't remember if there was anything special in making them.
也许是愚蠢的问题,但是您的BPI/BPL文件是否正确地由链接器找到?我曾经在BCB5中创建过一个应用程序,它使用了几个链接包,但不记得它们是否有什么特别之处。
#3
1
For me #pragma package(smart_init,weak) in the cpp file solved the problem. See also http://flylib.com/books/en/3.264.1.27/1/ The cpp->obj file gets staticly linked without influencing anything else.
对于我来说cpp文件中的#pragma包(smart_init,弱项)解决了这个问题。参见http://flylib.com/books/en/3.264.1.27/1/ cpp->obj文件得到静态链接,不影响任何其他内容。