std::stringを別のコンパイラで使うには?

このQ&Aのポイント
  • std::stringを別のコンパイラで使う場合の解決策とは?
  • セキュリティ上の問題を回避しながらstd::stringを外部に公開する方法
  • std::stringに関連する自作ソリューションの考え方とコードの最適化
回答を見る
  • ベストアンサー

std::stringを別のコンパイラで使うには?

例えばあるコンパイラでコンパイルしたコードの中に以下のような関数があったとします。 void func( std::string& str ); この関数をプラグインとか、DLLとか、外部に公開したいのです。 しかし、std::stringの実装方法はコンパイラ付属のライブラリに依存するため、プラグインを書く人が別のライブラリを使用した場合、致命的なエラーが発生する可能性があると思います。 (1)できればライブラリを指定したくない (2)std::stringを自作するような再発明は避けたい (3)全てをchar*(wchar_t*)で構成するようなことは避けたい この3つの要件を満たす解はあるのでしょうか? std::stringに関連するソースだけ(再配布可能なら)配布するとか? しかし、配布していいとは思えませんので、条件2をあきらめて自作しようかなと考えています。もしくは、条件3をあきらめようかと考えています。 <質問1>上記条件を満たす解はありますか? <質問2>自作する場合、どのようにコードを少なくしますか? <質問3>そもそもこのような事態に陥ってしまった時点で設計に問題があるのでしょうか?同様の問題に直面した場合、どのように対処されましたか? 以上 よろしくお願いします

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

> 条件2をあきらめて自作しようかなと考えています。 自作したとしても、コンパイラに依存することは避けられません。 > もしくは、条件3をあきらめようかと考えています。 こちらの方がやや現実的です。 コンパイラに依存しないDLLを作るのであれば、C++でなく、Cの関数にした方が融通が利きます。 # DLLから送出された例外も、コンパイラが異なると、どうしようもないですから。 また、すべてをchar*またはwchar_t*にしなくても、モジュールにまたがる部分だけそうすればよいのではないでしょうか。 つまり、DLLの中だけとか、アプリケーション側だけで使う分には、std::stringを好きなだけ使用してもよいと思います。

atushi256
質問者

お礼

回答ありがとうございます。 >> 条件2をあきらめて自作しようかなと考えています。 >自作したとしても、コンパイラに依存することは避けられません。 すいません、よくわからないのですが、何らかの問題が起こるのでしょうか?一般的なコンパイラで通るなら許容したい気持ちはあるのですが。(もちろんテンプレートのままにするつもりはありませんし、仮想関数や例外、継承も使用しないとします。) 唯一気になるのは、参照でstd::stringを渡しているということなのです。具体的な例が思い浮かびませんが、知識不足でいけると確信できない。(もっとも、ポインタに変更してもいいですが。) >> もしくは、条件3をあきらめようかと考えています。 > *以下略* これは確かにそうだと思います。

その他の回答 (1)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> すいません、よくわからないのですが、何らかの問題が起こるのでしょうか?一般的なコンパイラで通るなら許容したい気持ちはあるのですが。 コンパイラが異なれば、マングリングのルールが異なります。 すべてC結合にするならともかく、そうでなければリンクできなくなると思います。 > (もちろんテンプレートのままにするつもりはありませんし、仮想関数や例外、継承も使用しないとします。) 仮想関数や継承はともかく、std::stringを用いているのに例外も使わないのであれば、ほとんどの操作ができなくなります。

atushi256
質問者

お礼

>コンパイラが異なれば、マングリングのルールが異なります。 >すべてC結合にするならともかく、そうでなければリンクできなくなると思います。 なるほど。スタティクライブラリとして結合させればマングリングも大丈夫かなと思っていたのですが、コンパイラが異なるとそれもそうもいかないのか・・・。(たしかに言われてみれば、リンクする側はヘッダーを見て勝手にマングリングした名前で関数呼び出しをするプログラムを生成するけど、リンカで「見つからない」というエラーが出そうな気がします。) > 仮想関数や継承はともかく、std::stringを用いているのに例外も使わないのであれば、ほとんどの操作ができなくなります。 std::stringではなく、例外を出さない独自stringクラスを想定していました。 以上を踏まえると、jactaさんのおっしゃるように条件3をあきらめるのがベストのようですね・・・。(内部ではstd::stringを使うとして。)むー。 #Javaの様なほかの言語に移行しとけばよかったのかなぁ。 #レガシーがなければ移行したのですが。

atushi256
質問者

補足

捕捉にお礼を書くのもどうかと思いますが、条件3をあきらめることで決着がつきました。 どうもありがとうございました。

関連するQ&A

  • c++のstd::stringについて

    VC++2008でフォームアプリケーションを作成しています。 シリアルポートから受け取った文字列の一部を抜き出して処理をするため,VBではmid関数に相当するような機能として,std::stringを使用しようとしています。 しかし, std::string str("ABC" ,1,2); とした場合は『BC』が問題なく返ってきましたが, std::string str(recieveddata ,1,2); のように,文字列の部分を変数にしたら,ビルドエラーになってしまいます。(ポインタ?を理解する必要があるのでしょうか?) どのようにすれば,VBのmid相当の機能を実現できるでしょうか?

  • std::stringクラスのc_str()で取得した文字列をいじることは可能ですか?

    c++で、以下のようなコードは問題ないでしょうか? // chrの中身の小文字を大文字にする void func(char* chr); std::string str("aaa"); const char* str_p = std.c_str(); func((char*)str_p); ←これは大丈夫ですか? //このあとstrに対して文字列を追加したりいろいろ処理する。 このようにc_strで取得したconst char*をconstをはずして 強引にいじくることは問題ないでしょうか?

  • unsigned char SJis[2]からstd::stringに変換

    開発環境は VC++ 2008 Express Edition あるDLLの関数で戻り値としてShiftJISの1文字が格納された unsigned char SJis[2] が返され,これを呼び出し側のプログラムで使っている文字列 std::string str に順に追加していこうと思っています. そこで, unsigned char tmpSJis[3]; tmpSJis[0] = SJis[0]; tmpSJis[1] = SJis[1]; tmpSJis[2] = '\0'; str += std::string(tmpCode); というコードを書いてループさせたのですが, error C2440: '<function-style-cast>' : 'unsigned char *' から 'std::string' に変換できません。 というエラーが出てしまいうまく変換できません. これを解決する方法はありませんか?

  • std::wstringの継承

    #include<iostream> #include<string> #include <stdlib.h> #include <locale.h> #include <boost/lexical_cast.hpp> using boost::lexical_cast; using namespace std; VisualC++2008ExpressEditionで文字や数字を簡単に扱えるクラスを今作ろうとしていて以下のように作ってみました。 class multiString:public std::wstring{ public:   multiString(const wchar_t *ws){     /* multiString class自体に代入 */   } }; しかし、このwchar_tをクラスに代入する処理として、 multiString(const wchar_t *s)std::wstring(s); とすると、「error C2082: 仮パラメータ 's' が再定義されました。」となりますし、 multiString(const wchar_t *s)*this=s; とすると、例外が発生してしまします。 wstringだったら、簡単に代入処理として出来るのですが、継承した場合はどの様に実装すればいいのでしょうか? 宜しくお願いします。

  • コンパイラ、その周辺の質問

    C言語を勉強していて、いまいちわからなかったことを、ないがしろにしていたのでここで質問させてください。 ・あるプログラムをコンパイルするとまず機械語に翻訳されオブジェクトファイルができ、リンクすることでライブラリに登録されている関数のオブジェクトファイルと結合させ1つの実行ファイルを作るのですよね?(ここまでまちがいない?)  例えばprintf()を使ったときコンパイラはどのようにしてそのprintf()のオブジェクトファイルを探しているのかよくわかりません。ライブラリ(.lib)の働きも良くわかっていません。 VC++を使っておりますが、自作の関数をライブラリに登録する方法もできれば教えていただきたいです。 よろしくお願いします。

  • C/C++関数間でのStringクラスの扱い

    以下のようなコードを実行してみましたが思い通りに動いてくれません. "sample"という文字列がstrへとコピーされると思ったのですが. stringクラスのc_str()メソッドはconst char*だと言っているので無理矢理キャストしたのが原因でしょうか.stringクラスは記憶領域を自動で変更してくれるのではないのですか.それともこの挙動は仕様ですか. -------- 以下コード -------- #include <iostream> #include <string> using namespace std; int func(char *); int main(void) {     string str("");     func((char *)str.c_str());     cout << "String: " << str << endl;     return EXIT_SUCCESS; } int func(char *buf) {     buf = "sample";     return 0; } -------- 以上コード --------

  • キャストの仕方(std::stringをconst char*へ)を教えてください。

    c++で作成したものをコンパイルしたところ、 下記のようなエラーメッセージが表示されました。 cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int stat(const char*, stat*) 自分の解釈では、 stat関数の第1引数がconst char*なのに、 プログラムの中では  #include <sys/types.h>  #include <sys/stat.h>  using namespace std;   :  string aaa;   :  struct stat st;  if(stat(aaa,&st)!=-1){・・・   : という感じで記述しているので、 型が変換できない という感じのことを言っているのかなぁ・・・? と思っているのですが、間違いですか? また、間違えていないとしたら・・・、 このstringで宣言しているaaaをchar*(?)にキャストする方法 と言いますか、このエラーを解決する方法を教えてください。 毎度のことですが、理解不十分で、質問の意味が通じにくいかも しれませんが、どうか宜しくお願いいたします。m(_ _)m

  • コンパイラ、インタプリタ、クロスコンパイラについて

    インタプリタについて質問があります。 色々と調べたところ、perl、php、rubyなど、ソースをインタプリタで実行する言語の利点は以下なのだと思います。 ソフトを作っている環境と実行環境の間でcpuやos等が異なる場合は、 ソースは互いに異なる機械語に翻訳されるので、翻訳は実行環境で行わなければならない。 その際、コンパイラの場合はわざわざ手動で翻訳を実行しなければならないが、 インタプリタの場合は勝手に実行時に翻訳してくれるので楽。 1.それで質問なのですが、 コンパイラは環境に対応した機械語を出すらしいですが、 何故そんな事ができるのでしょうか。 コンパイラが、自身が置かれた環境を分析して、それに対応した機械語を出すのでしょうか? それとも、そもそも環境毎に対応したコンパイラを使うという事でしょうか? 2.また、世の中にはクロスコンパイラというものがあると聞きました。 クロスコンパイラがあれば、ソフトを作っている環境でそのままコンパイルできるので、 インタプリタはいらないのではないでしょうか? クロスコンパイラの短所や長所などを教えてほしいです。 3.翻訳後の話として、機械語はcpuやosによって違うという話ですよね。 つまり、機械語にコンパイル済みのソフトを配布する際は環境毎に対応したソフトを それぞれ配布しなければならないのですよね。 しかし、ネット上でダウンロードできるフリーのソフトなんかは、 特定のOS向け、あるいはOS別に違うファイルを配布、というのはよく見かけますが、 cpuやその他の環境毎に配布物を分けているのは見たことがありません。 機械語は、本当にos以外にも依存するものなのでしょうか?

  • STL string::findで見つからなかった時

    STL string::findで見つからなかった時の 書式を教えて下さい。 <-----ソース start-------> #define UNCODE #define _UNCODE #pragma warning( push,3 ) #pragma warning( disable : 4786 ) // 識別子が '255' 文字に切り捨 #include <iostream> #include <string> #include <vector> #pragma warning( pop ) #pragma warning( disable : 4514 ) // 参照されていないインライン関数は削除 #pragma warning( disable : 4786 ) // 識別子が '255' 文字に切り捨 int wmain(int iArgC, wchar_t* ArgV[], wchar_t* EnvP[]) {  setlocale( LC_ALL, "Japanese" );  std::vector<std::wstring> m_sEnv;  std::vector<std::wstring> m_sArg;  unsigned long lLoop;  unsigned long lPos;  for (lLoop=0; lLoop<(unsigned long)iArgC; lLoop++) {   m_sArg.push_back(ArgV[lLoop]);  }  for (lLoop=0;;lLoop++) {   if (EnvP[lLoop] == NULL) break;   m_sEnv.push_back(EnvP[lLoop]);  }  for (lLoop=0;lLoop<m_sEnv.size();lLoop++) {   if ((lPos = m_sEnv.at(lLoop).find(L"jdk1")) != npos) { // *1    std::wcout << m_sEnv.at(lLoop) << std::endl;   }  }  return 0; } <-----ソース end-------> *1 で error C2065: 'npos' : 定義されていない識別子です。 「std::npos」も試したけどだめだった。 >>以下MSDNより >>basic_string::npos >>static const size_type npos = -1; >>この定数は、size_type 型として表現できる最大の値です。 >>max_size() よりも大きいことが保証されるため、 >>非常に大きな値または特殊なコードとして使用できます。

  • stringクラスついて

    http://www.kumei.ne.jp/c_lang/cpp/cpp_62.htm この講座にある以下のコード(一部改変)を 実行しようとVisualStudio2005/WinXP環境で cppコンソールアプリケーションとして コンパイルしたところ、エラーが出てコンパイルできませんでした。 色々試行錯誤してみましたが、どうしても上手くいきません。 BorlandC/C++5.5コンパイラでは普通にコンパイルできましたが・・。 ひょっとしてMSのWin32に対応したstringクラスが他に用意されているのでしょうか? #include <iostream> #include <string> using namespace std; int main() { string s, t, u; s = "苗字"; t = "名前"; u = s + t; cout << u << endl; return 0; }

専門家に質問してみよう