2011-12-13 5 views
2

まず、私はC#プログラマです。したがって、私のC++に関する知識はかなり限られています。私は大学でそれを取り戻しましたが、10年後にそれに触れていないので、これが比較的単純なものであれば私を許してください。C++で2つのchar *を連結する関数

libwpdライブラリを実装するC#で使用できるDLLを作成しようとしています。

私はP/Invoke経由でアクセスできる2つの関数をエクスポートするDLLを作成することができました。最初は定数(Visual Studioによってサンプルとして生成されます)を返します.2番目の文字列です。

関数から定数の文字列を返すと、C#に正常に渡され、もう一方の端で読み取ることができるので、データが返されていることがわかります。

私が実行している問題は、libwpdです。私はTextDocumentGenerator.cppファイルを変更して、情報をchar *に追加する必要がありました。使用するprintfを使用するのではなく、後でアクセスすることができます。

ヘッダーファイルのパブリックセクションに変数定義を追加しました。これを呼び出しコードから読み取ることができます。

今、libwpdで与えられたchar *を外部char *に追加できるようにする関数を作成しようとしています。

私はこれを作ってみた:

char* addString(const char* addThis, char* toThis) 
{ 
char* copier = (char*)malloc(strlen(toThis) + 1 + 1); 
strcpy(copier, toThis); 
strcpy(copier, "1"); 

toThis = (char*)malloc(strlen(copier) + 1); 
strcpy(toThis, copier); 

return copier; 
} 

しかし、私は戻って情報を渡すとき、私は空の文字列を取得します。

私はSTRCATするのstrcpyを変更した場合、私は

(私はそれだけで技術的に繰り返し文字列に「1」を追加する必要があります実現が、それはそれさえもをやっていない)totalFile = addString("\n", totalFile);

を呼び出すことにより、関数を呼び出しますコピー機のライン、それはロックアップ。

私はC++でプログラムを作成する方法を知らないので、何が起きているのかを見るために関数をステップすることさえできます。

ご協力いただければ幸いです。

+0

'strcpy(複写機、toThis); strcpy(複写機、 "1"); ' - あるものについては、第2の' strcpy'が最初のファイルの結果を上書きします。 –

+0

C++で 'malloc'を使用していると、ほとんどの場合間違っていることを意味します。 C++で 'new'を使って自分自身を見つけたら、それはあなたが何か間違っていることを意味するかもしれません。 'new'が必要となる共通のシナリオの多くは標準テンプレートライブラリにすでに用意されています。 – Brian

+0

@Trevorフレンドリーなヒント:C++プロジェクトをC++/CLIとしてコンパイルすることをお勧めします。プロジェクトでは、ネイティブコード用のマネージラッパーを作成します。そうすれば、それはそれとのインターフェイスをより洗練されたものにします。いつものように参照を追加するだけで、ネイティブクラスへのアンマネージポインタを含むラッパーのマネージインスタンスを作成できます。 – Max

答えて

6

あなたはstd::stringの存在を認識していますか?これはC++の文字列を扱うクラスです。 char *はCからの遺産です。

std::stringは、あなたが望む通りに+オペレータを提供します。

+0

私はstd :: stringを認識していませんでした。私が使用しなければならなかった既存のコードと私の学校はchar *を使用していました。私はstd :: stringへのアクセス権を持っていないようです(インクルードがありません?)が、それを探します。 –

+0

彼はこれをc#から呼び出したいので、 'std :: string'は動作しません(少なくともパラメータと戻り値については)。 – crashmstr

+0

#include 。次回は、 "cppreference​​"のような情報を取得するために); – Griwes

2

リターン文字列に十分な領域を割り当て、インライン文字列を宛先バッファにコピーしてから、strcatを呼び出して余分な情報を追加する必要があります。例えば

char* addString(const char* addThis, const char* toThis) 
{ 
    char* destination = (char*)malloc(strlen(addThis) + strlen(toThis) + 1); 
    strcpy(destination, toThis); 
    strcat(destination, addThis); 
    return destination; 
} 

は、あなたがこの関数を呼び出した後、いくつかの点でfree(destination)を呼び出す必要があります忘れないでください。

編集: もちろん、これはあなたの質問に提案された機能を修正しているだけです。実際には、関数からポインタを返し、呼び出し元を解放して解放するのは良い考えではありません。あなたはCではなくC++を使用しているので、std :: stringや少なくともshared_ptrなどにchar *をラップするなど、C++の構文を使用するほうがはるかに良いでしょう。

C++を書くつもりなら、自分でa good bookを購入することをお勧めします。あなたが何をしているのか分からなければ、足で自分を撃つのは本当に簡単です。

+0

これは必ずしも良い考えではありません。あなたは割り当てたメモリのブロックを解放するために呼び出し元の責任を負います。これは 'shared_ptr'を使用しない場合ほど悪いです。あなたは記憶を割り当てて、 "それに気をつけろ"と言っています。いくつかは同意しないかもしれませんが、私はこの悪い習慣を見つけます。 –

+0

@ Moo-Juice私は個人的には、このような関数を書くことはないと思います。私はちょうど質問に提案された機能の混乱を修正していた。私が想定しているその旨の放棄を編集するかもしれません。 – obmarg

+0

最初のstrcmpは、私がそれを変更したときにロックする原因となっていました。これをstrcpy/strcmpとして実行すると、この時点を過ぎて実行できます。私はおそらく、sprintfまたはstd :: stringを見ていきます。もし私がリンクエラーを越えることができれば。コメントありがとう! –

1

printf()コールを交換するので、おそらくsprintf()が文字列を作成する最も簡単な方法でしょう。

+0

必要なインクルードがlibwpdを壊すまで、これは比較的有望でした。コメントありがとう! –

+0

@ Trevor: 'printf'にも必要なものと同じものが必要です。' 'ヘッダです。 – sth

0

最初に、Griwesは正しいです。あなたはあなたがやっていることをやっておらず、この質問をC++としてマークしています。簡単な理由は、これはC++で文字列を処理する方法ではありません。

C#プログラマは、Stringクラスをよく知っています。まあ、std::stringは似ています。あなたが倒れている苦しいルートを降りる必要がないように、紐を扱うことから脚を取り除きます。 C++で一緒に2つの文字列を連結する

、それは同じくらい簡単です:

std::string a = "I slept with "; 
std::string b = "a heavy heart."; 
std::string c = a + b; 

出来上がり。

+0

これの欠点は、レガシーコードまたはchar *で書かれたコードを使用していることです。あなたはstd :: stringをchar *に変換して、問題なく再利用できますか?また、std :: stringへのアクセス権もありません(インクルードがどこかにありません)。学校や私が修正している既存のソースコードではchar *が使われていたのでchar *を使用しました。もし私がそれにアクセスできるなら、私は間違いなくstd :: stringを調べます。 –

+1

@TrevorWatson、はい。上の例では、 'c.c_str()'を呼び出すと、通常の 'const char *'が得られます。 –

+0

@TrevorWatson: 'std :: string'は標準テンプレートライブラリの一部です。これはまともなC++コンパイラに含まれています。 'std :: string'の代わりに' char * 'を使うのは、' System.String'を使うのではなく、C#で 'char []'を使うのと似ています。 – Brian

関連する問題