第一次接触Managed C++,下面只是个人的感触,写的不对的地方请指出来。
用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