// // DLL開発簡略化テンプレート // System4.0 <=> C++ 相互変換 配列・構造体テンプレート // // Akt. // // 例えば、System4.0 で、array@int の配列をHLLに渡したとすると、 // 通常は、IVMArray2で受け取って、GetDataとか駆使していじくったりします。 // structだと、IVMStruct3で受け取って、GetDataや名前から引いたりしていろいろやります。 // でもまぁ、非常にめんどくさいです。 // なので、それを簡略化するテンプレートがコレです。 //★配列テンプレート // 先の例で、array@intは、IVMArray2で受け取りますが、 // それを、s4Array のコンストラクタにつっこんでやると // vector っぽく使えます。 // さらに値を編集したり、push_backとか使っても、 // System4.0に処理が戻った(デストラクタが呼ばれる)ときに反映されます。 // ( ただし、HLLライブラリには、ref array@int ってかかないといけない ) // // ちなみに、文字列の場合は、 // array@string で渡された、IVMArray2を // s4Array のコンストラクタに渡すと、 // vector として扱えます。ものすっごい便利です。 //★構造体テンプレート // 構造体では、struct で渡すと、IVMStruct3で受け取りますが、 // それを、s4Structのコンストラクタにつっこむと、 // ポインタ参照( -> )でstructのメンバが扱えます。 // 注意: // ただし、System4.0と全く同じ構造を持つ、構造体をC++で記述します。 // また、#pragma pack(push,1)を使って、アライメントを調整します。 // 詳細はサンプルを参照。 // // これまた同様に、System4.0に処理が戻る(デストラクタが呼ばれる)と中身が移されます。 // 非常においしいテンプレートです。でも、refとかが使われてるテンプレートには利用できません。 // ただ、構造体の中の「構造体」・構造体の中の「配列の構造体」だと、IVMStruct3*と、s4Arrayで構造体を書いてください。 // 構造体の中の「整数配列」や「文字列配列」なら、s4Arrayや、s4Arrayで、構造体に書きます。 #include #include #include #include "Interface\IString.h" #include "Interface\IVMStruct3.h" #include "Interface\IVMArray2.h" #include "Interface\EObjType42.h" using namespace std; template class s4Array { std::vector v; IVMArray2* m_pArray; bool m_ro; public: s4Array(){ m_pArray=NULL; } s4Array(IVMArray2* pArray,bool ReadOnly=false){ Bind(pArray,ReadOnly); } void Bind(IVMArray2* pArray,bool ReadOnly=false){ m_ro=ReadOnly;m_pArray=pArray; int type=m_pArray->GetType(); for(int i=0;iGetNumof();i++){ T* dt=(T*)m_pArray->GetData(i); v.push_back(*dt); } } T& operator[](int index) { return v[index]; } std::vector* operator->() { return &v; // 自分自身へのポインタを返す。 } void UnBind(){ if(m_pArray==NULL) return; if(m_ro) return; int type=m_pArray->GetType(); if(v.size()!=m_pArray->GetNumof()){ int count=v.size(); m_pArray->Alloc(&count, 1); } for(int i=0;iGetNumof();i++){ m_pArray->SetData(i,(void*)(&v[i])); } } ~s4Array(void){ UnBind(); } }; template <> class s4Array { std::vector v; IVMArray2* m_pArray; bool m_ro; public: s4Array(){ m_pArray=NULL; } s4Array(IVMArray2* pArray,bool ReadOnly=false){ Bind(pArray,ReadOnly); } void Bind(IVMArray2* pArray,bool ReadOnly=false){ m_ro=ReadOnly;m_pArray=pArray; int type=m_pArray->GetType(); for(int i=0;iGetNumof();i++){ IString* dt=(IString*)m_pArray->GetData(i); v.push_back(dt->Get()); } } string& operator[](int index) { return v[index]; } std::vector* operator->() { return &v; // 自分自身へのポインタを返す。 } void UnBind(){ if(m_pArray==NULL) return; if(m_ro) return; int type=m_pArray->GetType(); if(v.size()!=m_pArray->GetNumof()){ int count=v.size(); m_pArray->Alloc(&count, 1); } for(int i=0;iGetNumof();i++){ m_pArray->SetData(i,(void*)(v[i].c_str())); } } ~s4Array(void){ UnBind(); } }; template <> class s4Array { std::vector v; IVMArray2* m_pArray; bool m_ro; public: s4Array(){ m_pArray=NULL; } s4Array(IVMArray2* pArray,bool ReadOnly=false){ Bind(pArray,ReadOnly); } void Bind(IVMArray2* pArray,bool ReadOnly=false){ m_ro=ReadOnly;m_pArray=pArray; int type=m_pArray->GetType(); for(int i=0;iGetNumof();i++){ IVMStruct3* dt=(IVMStruct3*)m_pArray->GetData(i); v.push_back(dt); } } (IVMStruct3*)& operator[](int index) { return v[index]; } std::vector* operator->() { return &v; // 自分自身へのポインタを返す。 } void UnBind(){ if(m_pArray==NULL) return; if(m_ro) return; int type=m_pArray->GetType(); if(v.size()!=m_pArray->GetNumof()){ int count=v.size(); m_pArray->Realloc(&count, 1); } //データを戻さない } ~s4Array(void){ UnBind(); } }; template class s4Struct { IVMStruct3* m_pStruct; bool m_ro; T d; private: int CopyOnce(void** r_dst,void** r_src,int type,bool w){ void* dst=*r_dst; void* src=*r_src; switch(type){ case EObjType::OBJTYPE_INT: case EObjType::OBJTYPE_R_INT: *((int*)(dst)) = *((int*)src); return sizeof(int); case EObjType::OBJTYPE_FLOAT: *((float*)(dst)) = *((float*)src); return sizeof(float); case EObjType::OBJTYPE_BOOL: *((bool*)(dst)) = *((bool*)src); return sizeof(bool); case EObjType::OBJTYPE_STRING: if(w){ *(string*)(dst) = ((IString*)src)->Get(); }else{ char* dt=(char*)(((string*)src)->c_str()); ((IString*)(dst))->Set( dt ); } return sizeof(string); case EObjType::OBJTYPE_STRUCT: if(w){ //**r_dst=*r_src; *(IVMStruct3**)(dst)=*((IVMStruct3**)r_src); //*((IVMStruct3**)r_dst)=*((IVMStruct3**)r_src); //*((IVMStruct3**)(dst)) = *((IVMStruct3**)src); }else{ } return sizeof(IVMStruct3*); case EObjType::OBJTYPE_A_INT: if(w){ ((s4Array *)(dst))->Bind( (IVMArray2*)src ); }else{ ((s4Array *)(src))->UnBind(); } return sizeof(s4Array); case EObjType::OBJTYPE_A_FLOAT: if(w){ ((s4Array *)(dst))->Bind( (IVMArray2*)src ); }else{ ((s4Array *)(src))->UnBind(); } return sizeof(s4Array); case EObjType::OBJTYPE_A_BOOL: if(w){ ((s4Array *)(dst))->Bind( (IVMArray2*)src ); }else{ ((s4Array *)(src))->UnBind(); } return sizeof(s4Array); case EObjType::OBJTYPE_A_STRING: if(w){ ((s4Array *)(dst))->Bind( (IVMArray2*)src ); }else{ ((s4Array *)(src))->UnBind(); } return sizeof(s4Array); case EObjType::OBJTYPE_A_STRUCT: if(w){ ((s4Array *)(dst))->Bind( (IVMArray2*)src ); }else{ ((s4Array *)(src))->UnBind(); } return sizeof(s4Array); } } public: s4Struct(IVMStruct3* pStruct,bool ReadOnly=false){ m_ro=ReadOnly;m_pStruct=pStruct; byte* pter=(byte*)&d; int pp=0; for(int i=0;iGetNumof();i++){ int type=m_pStruct->GetType(i); void* val=m_pStruct->GetData(i); void* pnow=(void*)(pter+pp); pp+=CopyOnce(&pnow,&val,type,true); } } T* operator->() { return &d; // 自分自身へのポインタを返す。 } ~s4Struct(void){ if(m_ro) return; byte* pter=(byte*)&d; int pp=0; for(int i=0;iGetNumof();i++){ int type=m_pStruct->GetType(i); void* val=m_pStruct->GetData(i); void* pnow=(void*)(pter+pp); pp+=CopyOnce(&val,&pnow,type,false); } } };