private ParameterDef BuildParameter(XElement parameterNode, List <Tuple <string, string> > argParams) { var def = new ParameterDef(); def.Name = parameterNode.Element("parameternamelist").Element("parametername").Value; def.Brief = parameterNode.Element("parameterdescription").Element("para").Value; var arg = argParams.FirstOrDefault(_ => _.Item2 == def.Name); if (arg != null) { def.Type.Parse(settings, arg.Item1); } return(def); }
public void Export(string libDirPath, string dllDirPath) { string dllH_Header = @" #pragma once #include <stdio.h> #include <stdint.h> #include <memory> #include <vector> #include <asd.common.Base.h> #include ""asd.Core.Base.h"" extern ""C"" { ASD_DLLEXPORT void* ASD_STDCALL CreateWrapperDLL(); ASD_DLLEXPORT void ASD_STDCALL DeleteWrapperDLL(void* o); } namespace asd { "; string dllH_Footer = @" }; "; string dllCpp_Header = @" #include ""asd.WrapperDLL.h"" #include ""Sound/asd.Sound.h"" #include ""Sound/asd.SoundSource.h"" #include ""IO/asd.File.h"" #include ""IO/asd.StaticFile.h"" #include ""IO/asd.StreamFile.h"" #include ""Graphics/Media/asd.MediaPlayer.h"" #include ""Tool/asd.Tool.h"" namespace asd { "; string dllCpp_Footer = @" }; extern ""C"" { ASD_DLLEXPORT void* ASD_STDCALL CreateWrapperDLL() { return new asd::WrapperDLL(); } ASD_DLLEXPORT void ASD_STDCALL DeleteWrapperDLL(void* o) { auto o_ = (asd::WrapperDLL*)o; delete o_; } } "; string libH_Header = @" #pragma once #include <stdio.h> #include <stdint.h> #include <memory> #include <vector> #include ""asd.CoreToEngine.h"" namespace asd { "; string libH_Footer = @" }; "; string libCpp_Header = @" #include ""asd.WrapperLib.h"" #include ""asd.WrapperLib.Internal.h"" #include ""asd.CoreToEngine.h"" namespace asd { static WrapperDLL* dll = nullptr; void InitializeWrapper(CreateWrapperDLLFunc func) { dll = (WrapperDLL*)func(); }; void TerminateWrapper(DeleteWrapperDLLFunc func) { func(dll); }; "; string libCpp_Footer = @" }; "; string StreamFile_Additional = @" /** @brief 指定したサイズ分、ファイルを読み込む。 @param buffer 出力先 @param size 読み込まれるサイズ */ void Read(std::vector<uint8_t>& buffer, int32_t size) { auto result = Read(size); buffer.resize(result); memcpy(buffer.data(), GetTempBuffer(), result); } "; AddDLLH(dllH_Header); AddDLLH("class " + dllClassName + " {"); AddDLLH("public:"); AddDLLCPP(dllCpp_Header); AddLIBH(libH_Header); AddLIBCPP(libCpp_Header); PushDLLHIndent(); // predefined foreach (var c in doxygen.ClassDefs) { if (!settings.ClassWhiteList.Any(_ => _ == c.Name)) { continue; } AddLIBH("class " + c.Name + ";"); } AddLIBH("class AutoGeneratedWrapperAccessor;"); AddLIBH(""); foreach (var c in doxygen.ClassDefs) { if (!settings.ClassWhiteList.Any(_ => _ == c.Name)) { continue; } var dllFuncPrefix = c.Name + "_"; AddLIBH("/**"); AddLIBH("\t@brief " + c.Brief); AddLIBH("*/"); AddLIBH("class " + c.Name + " {"); PushLIBHIndent(); AddLIBH("void* self = nullptr;"); AddLIBH("bool isCtrlSelf = false;"); // friend class (TODO smart) foreach (var c2 in doxygen.ClassDefs) { if (!settings.ClassWhiteList.Any(_ => _ == c2.Name)) { continue; } AddLIBH("friend class " + c2.Name + ";"); } foreach (var c2 in settings.FriendClassList) { AddLIBH("friend class " + c2 + ";"); } AddLIBH("friend class AutoGeneratedWrapperAccessor;"); // Default constructor if (!c.Methods.Any(m => string.IsNullOrEmpty(m.ReturnType.Name) && !m.Name.Contains("~") && m.IsPublic)) { AddLIBH(c.Name + "(void* self, bool isCtrlSelf);"); AddLIBCPP(c.Name + "::" + c.Name + "(void* self, bool isCtrlSelf) {"); AddLIBCPP("\tthis->self = self;"); AddLIBCPP("\tthis->isCtrlSelf = isCtrlSelf;"); AddLIBCPP("}"); } bool isDestructorPrivate = c.Methods.Any(_ => _.Name.Contains("~") && !_.IsPublic); AddLIBH("public:"); foreach (var m in c.Methods) { if (m.IsStatic) { continue; } var isConstract = string.IsNullOrEmpty(m.ReturnType.Name) && !m.Name.Contains("~"); var isDestruct = string.IsNullOrEmpty(m.ReturnType.Name) && m.Name.Contains("~"); // A method note is none if (string.IsNullOrEmpty(m.Brief) && !isConstract && !isDestruct) { continue; } // A method whose note has a #Ignore is ignored. if (m.Note?.Contains("#Ignore") ?? false) { continue; } // A method which has an argument whose type is shared_ptr<T> is ignored. if (m.Parameters.Any(_ => _.Type.IsSharedPtr)) { continue; } // A method whose return type is shared_ptr<T> is ignored. if (m.ReturnType.IsSharedPtr) { continue; } // non public functions are not valid without destructor if (!isDestruct && !m.IsPublic) { continue; } var methodName = m.Name; var returnType = m.ReturnType; var libParameters = m.Parameters.ToArray().ToList(); var dllParameters = m.Parameters.ToArray().ToList(); if (isConstract) { methodName = "Construct"; returnType.Name = "void *"; } else if (isDestruct) { methodName = "Destruct"; returnType.Name = "void"; ParameterDef def = new ParameterDef(); def.Type.Name = "void *"; def.Name = "self"; dllParameters.Insert(0, def); } else { ParameterDef def = new ParameterDef(); def.Type.Name = "void *"; def.Name = "self"; dllParameters.Insert(0, def); } var dllFuncName = dllFuncPrefix + methodName; // dll var dllFuncArg = "(" + string.Join(",", dllParameters.Select((_, i) => GetDLLHArg(_.Type, m) + " " + _.Name).ToArray()) + ")"; // dll header AddDLLH("virtual " + GetDLLRet(returnType, m) + " " + dllFuncName + dllFuncArg + ";"); // dll cpp AddDLLCPP(GetDLLRet(returnType, m) + " " + dllClassName + "::" + dllFuncName + dllFuncArg + "{"); PushDLLCppIndent(); if (isConstract) { var argConverters = libParameters.Select((_, i) => GetDLLCppArg(_.Type, i, _.Name, m)); foreach (var a in argConverters) { AddDLLCPP(a); } AddDLLCPP("return " + c.Name + "(" + string.Join(",", libParameters.Select((_, i) => "arg" + i).ToArray()) + ");"); } else if (isDestruct) { AddDLLCPP("auto self_ = (" + c.Name + "*)self;"); var f = GetDLLDestructor(new TypeDef() { Name = c.Name }, !m.IsPublic); if (f != "") { AddDLLCPP(f); } } else { AddDLLCPP("auto self_ = (" + c.Name + "*)self;"); var argConverters = libParameters.Select((_, i) => GetDLLCppArg(_.Type, i, _.Name, m)); foreach (var a in argConverters) { AddDLLCPP(a); } if (returnType.Name == "void" && !returnType.IsPointer) { AddDLLCPP("self_->" + methodName + "(" + string.Join(",", libParameters.Select((_, i) => "arg" + i).ToArray()) + ");"); } else { var retType = "auto"; if (returnType.IsRef) { retType = "auto&"; } AddDLLCPP(retType + " ret = self_->" + methodName + "(" + string.Join(",", libParameters.Select((_, i) => "arg" + i).ToArray()) + ");"); AddDLLCPP(GetDLLCppRet(returnType, m)); } } PopDLLCppIndent(); AddDLLCPP("};"); AddDLLCPP(""); // lib var libFuncArg = "(" + string.Join(",", libParameters.Select(_ => GetLIBHArg(_.Type, m) + " " + _.Name).ToArray()) + ")"; if (m.IsConst) { libFuncArg += " const"; } // lib header AddLIBH("/**"); AddLIBH("\t@brief " + m.Brief); foreach (var p in m.Parameters) { AddLIBH("\t@param " + p.Name + " " + p.Brief); } if (!string.IsNullOrEmpty(m.BriefOfReturn)) { AddLIBH("\t@return " + m.BriefOfReturn); } AddLIBH("*/"); if (isConstract) { AddLIBH(c.Name + libFuncArg + ";"); } else if (isDestruct) { AddLIBH("virtual ~" + c.Name + libFuncArg + ";"); } else { AddLIBH(GetLIBRet(returnType, m) + " " + methodName + libFuncArg + ";"); } AddLIBH(""); // lib cpp if (isConstract) { AddLIBCPP(c.Name + "::" + c.Name + libFuncArg + "{"); PushLIBCppIndent(); { AddLIBCPP("auto arg0 = self;"); var argConverters = libParameters.Select((_, i) => GetLIBCppArg(_.Type, i + 1, _.Name, m)); foreach (var a in argConverters) { AddLIBCPP(a); } AddLIBCPP("self = dll->" + dllFuncName + "(" + string.Join(",", dllParameters.Select((_, i) => "arg" + i).ToArray()) + ");"); AddLIBCPP("isCtrlSelf = true;"); } PopLIBCppIndent(); AddLIBCPP("};"); } else if (isDestruct) { AddLIBCPP(c.Name + "::~" + c.Name + libFuncArg + "{"); PushLIBCppIndent(); { AddLIBCPP("if (isCtrlSelf) {"); PushLIBCppIndent(); AddLIBCPP("dll->" + dllFuncName + "(" + string.Join(",", dllParameters.Select(_ => _.Name).ToArray()) + ");"); PopLIBCppIndent(); AddLIBCPP("}"); } PopLIBCppIndent(); AddLIBCPP("};"); } else { AddLIBCPP(GetLIBRet(returnType, m) + " " + c.Name + "::" + methodName + libFuncArg + "{"); PushLIBCppIndent(); { AddLIBCPP("auto arg0 = self;"); var argConverters = libParameters.Select((_, i) => GetLIBCppArg(_.Type, i + 1, _.Name, m)); foreach (var a in argConverters) { AddLIBCPP(a); } if (returnType.Name == "void" && !returnType.IsPointer) { AddLIBCPP("dll->" + dllFuncName + "(" + string.Join(",", dllParameters.Select((_, i) => "arg" + i).ToArray()) + ");"); } else { var retType = "auto"; if (returnType.IsRef) { retType = "auto&"; } AddLIBCPP(retType + " ret = dll->" + dllFuncName + "(" + string.Join(",", dllParameters.Select((_, i) => "arg" + i).ToArray()) + ");"); AddLIBCPP(GetLIBCppRet(returnType, m)); } } PopLIBCppIndent(); AddLIBCPP("};"); } AddLIBCPP(""); } if (c.Name == "StreamFile") { AddLIBH(StreamFile_Additional); } PopLIBHIndent(); AddLIBH("};"); AddLIBH(""); } PopDLLHIndent(); AddDLLH("};"); AddDLLH(dllH_Footer); AddDLLCPP(dllCpp_Footer); AddLIBH(libH_Footer); AddLIBCPP(libCpp_Footer); System.IO.File.WriteAllLines(dllDirPath + "asd.WrapperDLL.h", dll_headerText.ToArray(), System.Text.Encoding.UTF8); System.IO.File.WriteAllLines(dllDirPath + "asd.WrapperDLL.cpp", dll_cppText.ToArray(), System.Text.Encoding.UTF8); System.IO.File.WriteAllLines(libDirPath + "asd.WrapperLib.h", lib_headerText.ToArray(), System.Text.Encoding.UTF8); System.IO.File.WriteAllLines(libDirPath + "asd.WrapperLib.cpp", lib_cppText.ToArray(), System.Text.Encoding.UTF8); }