用C#写dll工程时,还以为也要用到dllexport之类的玩艺,后来才知道只要导出的函数声明为public就行。
可是dll搞出来后,要调用dll里的函数需要用到Managed C++ ,而用native C++是不可以的。还有就是用到C#的dll时,还以为要加头文件,加库文件,后来只需要#using "....dll"就行。而这样呢,managed c++工程就起到了适配器的功能。我用managed c++工程把C#生成的dll包装一下再导出,让native c++工程去调用这个包装好的dll。
当然这里我要推荐一个哥们的blog:
http://www.cppblog.com/mzty/archive/2007/12/25/39555.html
对了,要注意将如果要用到Managed C++,需要将工程(C++)工程配置文件中的Common Language Runtime Support选上。
后来我就自己去做了个实验,dll成功生成,但是在Managed C++的工程编译时,有个编译错误很是恼人,后来对比上面那个哥们的代码和我的程序,发觉没有什么区别。于是就开始怀疑工程配置文件了。
编译错误如下:
>./dllmain.cpp(32) : error C3624: 'System::Windows::Forms::UserControl': use of this type requires a reference to assembly 'System.Windows.Forms'
这个错误对于初学者来说是有点困难的,我想大概是因为我用到的UserControl没有.net类库去对应,才报那样错。可是自己在源文件里加using System.Windows.Forms根本不起作用,后来就对照代码,也没错误。
那样的话只有看工程配置文件了。
那哥们工程配置文件如下:
<?xml version="1.0" encoding="gb2312"?> <VisualStudioProject ProjectType="Visual C++" Version="8.00" Name="CppCLIProxyDLLForCsharpDLL" ProjectGUID="{4F30E449-C625-4A10-8A12-59F09F923F1F}" RootNamespace="CppCLIProxyDLLForCsharpDLL" Keyword="Win32Proj" > <Platforms> <Platform Name="Win32" /> </Platforms> <ToolFiles> </ToolFiles> <Configurations> <Configuration Name="Debug|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="2" CharacterSet="1" ManagedExtensions="1" > <Tool Name="VCPreBuildEventTool" /> <Tool Name="VCCustomBuildTool" /> <Tool Name="VCXMLDataGeneratorTool" /> <Tool Name="VCWebServiceProxyGeneratorTool" /> <Tool Name="VCMIDLTool" /> <Tool Name="VCCLCompilerTool" Optimization="0" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;CPPCLIPROXYDLLFORCSHARPDLL_EXPORTS" MinimalRebuild="false" BasicRuntimeChecks="0" RuntimeLibrary="3" UsePrecompiledHeader="2" WarningLevel="3" Detect64BitPortabilityProblems="true" DebugInformationFormat="3" /> <Tool Name="VCManagedResourceCompilerTool" /> <Tool Name="VCResourceCompilerTool" /> <Tool Name="VCPreLinkEventTool" /> <Tool Name="VCLinkerTool" LinkIncremental="2" GenerateDebugInformation="true" AssemblyDebug="1" SubSystem="2" TargetMachine="1" /> <Tool Name="VCALinkTool" /> <Tool Name="VCManifestTool" /> <Tool Name="VCXDCMakeTool" /> <Tool Name="VCBscMakeTool" /> <Tool Name="VCFxCopTool" /> <Tool Name="VCAppVerifierTool" /> <Tool Name="VCWebDeploymentTool" /> <Tool Name="VCPostBuildEventTool" /> </Configuration> <Configuration Name="Release|Win32" OutputDirectory="$(SolutionDir)$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="2" CharacterSet="1" WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" /> <Tool Name="VCCustomBuildTool" /> <Tool Name="VCXMLDataGeneratorTool" /> <Tool Name="VCWebServiceProxyGeneratorTool" /> <Tool Name="VCMIDLTool" /> <Tool Name="VCCLCompilerTool" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;CPPCLIPROXYDLLFORCSHARPDLL_EXPORTS" RuntimeLibrary="2" UsePrecompiledHeader="2" WarningLevel="3" Detect64BitPortabilityProblems="true" DebugInformationFormat="3" /> <Tool Name="VCManagedResourceCompilerTool" /> <Tool Name="VCResourceCompilerTool" /> <Tool Name="VCPreLinkEventTool" /> <Tool Name="VCLinkerTool" LinkIncremental="1" GenerateDebugInformation="true" SubSystem="2" OptimizeReferences="2" EnableCOMDATFolding="2" TargetMachine="1" /> <Tool Name="VCALinkTool" /> <Tool Name="VCManifestTool" /> <Tool Name="VCXDCMakeTool" /> <Tool Name="VCBscMakeTool" /> <Tool Name="VCFxCopTool" /> <Tool Name="VCAppVerifierTool" /> <Tool Name="VCWebDeploymentTool" /> <Tool Name="VCPostBuildEventTool" /> </Configuration> </Configurations> <References> <AssemblyReference RelativePath="System.Windows.Forms.dll" AssemblyName="System.Windows.Forms, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" /> <AssemblyReference RelativePath="System.dll" AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" /> </References> <Files> <Filter Name="Source Files" Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > <File RelativePath="./CppCLIProxyDLLForCsharpDLL.cpp" > </File> <File RelativePath="./stdafx.cpp" > <FileConfiguration Name="Debug|Win32" > <Tool Name="VCCLCompilerTool" UsePrecompiledHeader="1" /> </FileConfiguration> <FileConfiguration Name="Release|Win32" > <Tool Name="VCCLCompilerTool" UsePrecompiledHeader="1" /> </FileConfiguration> </File> </Filter> <Filter Name="Header Files" Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > <File RelativePath="./CppCLIProxyDLLForCsharpDLL.h" > </File> <File RelativePath="./stdafx.h" > </File> </Filter> <Filter Name="Resource Files" Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" > </Filter> <File RelativePath="./ReadMe.txt" > </File> </Files> <Globals> </Globals> </VisualStudioProject>
根据编译错误的信息,再结合配置文件,可以锁定自己没有将配置文件搞好。
在配置文件的common properties里面中的References: 点击Add New References,添加System.Windows.Forms即可。当然了还有一个比较简单方法就是在.h文件中写一句话:#using <System.Windows.Forms.dll>
晚上回家偶尔上网搜了一下,关于C++/CLI方面的书籍(不错):
http://www.visionopen.com/smf/index.php?PHPSESSID=pmbdio79cuko8hl7nublknjbg3&topic=317.0此网站介绍了以下几个网址:
http://msdn.microsoft.com/en-us/library/ms379617.aspx
Standard ECMA-372 C++/CLI Language Specification!
http://www.ecma-international.org/publications/standards/Ecma-372.htm
http://www.gotw.ca/publications/C++CLIRationale.pdf