【初心者歓迎】C/C++室 Ver.70【環境依存OK】

このエントリーをはてなブックマークに追加
952デフォルトの名無しさん:2010/01/26(火) 22:51:58
リンカの動作は規格で定めるものじゃないんだからわからんとしか…
気になるなら分けておけばいいじゃん
953デフォルトの名無しさん:2010/01/26(火) 22:54:20
環境依存OKなスレだから、規格で決まっていないことを質問しても問題は無い
954デフォルトの名無しさん:2010/01/26(火) 23:01:15
環境依存の質問がダメって言ったつもりはなかったんだが
まぁすまんかった
955デフォルトの名無しさん:2010/01/26(火) 23:05:20
DLLが公開してる関数のようにEXEから関数を公開する事はできますか?
956デフォルトの名無しさん:2010/01/27(水) 00:56:53
>>955
関数を公開することはできる。やり方はDLLの場合と同じ。
ただし、DLLとして読み込むのは難しいと思う。できる方法を自分は知らない。
957デフォルトの名無しさん:2010/01/27(水) 09:41:14
>>952-954
申し訳ありませんでした。
規格によってリンク時の動作が決まっているものではない
ということを知らなかったのです。

ちなみに、VC6やVC2005やVC2008のリンカだと
使っていないものはリンク時に外してくれるものなのでしょうか?
「便利クラス&関数群」みたいなライブラリを作ろうかと思ったのですが。
958デフォルトの名無しさん:2010/01/27(水) 10:14:56
だからobjファイルごとだって。
どこからも参照されてないobjはリンクされないが、一か所でも使われてるとobj全部リンクされる。
関連の無いものはそれぞれ別のc/c++ファイルにしておけばいいよ
959デフォルトの名無しさん:2010/01/27(水) 10:20:20
補足しておくと、libはobjファイルを集めたもの。
1個の.Cファイルをコンパイルしてobjを作り、それをlibにしたら常に全部リンクされる。
関数一つ一つばらしておけば、使ってるやつだけリンクされる。
960デフォルトの名無しさん:2010/01/27(水) 10:35:18
>>958-959
そういうことでしたか。
基本的にはクラスごとにソースは分けてあるので、
ライブラリ自体は1つにまとめてビルドしてしまっても、
アプリケーションが使っていないクラスは
リンク時に捨ててくれるということですね。
961デフォルトの名無しさん:2010/01/27(水) 11:59:47
配列&文字列は、参照私できないの?
962デフォルトの名無しさん:2010/01/27(水) 12:10:30
できるぞ
#include <iostream>
void foo(int (&a)[10]) {
a[0] = 42;
}
int main() {
int a[10];
foo(a);
std::cout << a[0] << std::endl;
}
963デフォルトの名無しさん:2010/01/27(水) 12:42:37
要素数固定なのか、うむポインタにしよう
964デフォルトの名無しさん:2010/01/27(水) 13:31:06
可変にできないこともない
#include <iostream>
template <int N>
void foo(int (&a)[N]) {
a[0] = 42;
};
int main() {
int a[10];
foo(a);
std::cout << a[0] << std::endl;
}
965デフォルトの名無しさん:2010/01/27(水) 15:44:55
>>956
難しいですか
DLLにコールバック関数を持たせてアプリケーションを拡張できるように・・・というのをやろうとしてるんですが
そうなるとAPIを提供する仲介用DLLと拡張用DLLを両方用意しないと駄目みたいですね
レスどうもでした
966デフォルトの名無しさん:2010/01/27(水) 16:17:46
>>965
アプリケーションを拡張できるように

アプリケーション側が
 決まった関数名 を エクスポートする DLL を LoadLibaray で取り込む→GetProcAddress でDLL側の関数保持
 状況に応じて その DLL 内関数を呼び出す
こういう構造を容易しておいて

拡張を記述する側は
 アプリケーション側の呼び出しルールに応じた 関数を書けばOK

こういう造りが多いんじゃね?
967デフォルトの名無しさん:2010/01/27(水) 18:30:16
>>965
EXE内で定義した関数を、関数へのポインタとしてDLL内の関数へ渡すのはできるよ。
難しいと書いたのはEXEファイルをLoadLibraryしたりLIBでリンクしたりということ。俺の勘違いだったらすまない。
968デフォルトの名無しさん:2010/01/27(水) 18:34:47
横槍すまない。

>>964
すげー。以下のようなコードを書いたら通ってしまった。
スタティック配列始まったな。

template<class T,size_t N>
void Init(T (&Array)[N]){
    T Val(0);
    for(size_t i=0;i<N;i++){
        Array[i] = Val;
    }
}
969933-940:2010/01/27(水) 18:35:14
先日は色々ご教授ありがとうございました。

色々調べまくった結果、

scanf("%[abcre12345]",&c);

この部分を

scanf("%c",&c);

こうすることで何とか解決することが出来ました。

ありがとうございました。

これで何とかなりそうです。
970デフォルトの名無しさん:2010/01/27(水) 21:23:30
>>966,967
レスサンクスです
EXE側のオブジェクトを操作するのに操作用のAPIをDLLで提供しなければいけないかなと思ったんですが、なんとか拡張用DLLだけでできそうです
レスをまとめるとこんな感じですかね

//--Main側--
class Hoge
{
public:
Hoge(void) { /* DLLからHogeUpdateをロード */ }
void Update(void);
void SetX(int x) { m_x = x; }
int GetX(void) { return m_x; }
private:
int m_x;
void (*m_HogeUpdate)(void *handle, HogeFunc *hogeFunc); // コールバック用の関数ポインタ
};

//公開する関数
void HogeSetX(void *handle, int x) { ((Hoge *)handle)->SetX(x); }
int HogeGetX(void *handle) { return ((Hoge *)handle)->GetX(); }

struct HogeFunc { void (*SetX)(void *handle, int x); int (*GetX)(void *handle); };

//拡張用関数をコール
void Hoge::Update(void) { HogeFunc hogeFunc = { HogeSetX, HogeGetX }; m_HogeUpdate(this, &hogeFunc); }

//--DLL側--
//公開する関数
void HogeUpdate(void *handle, HogeFunc *hogeFunc) { /* 拡張によって異なる。handleとhogeFuncでオブジェクトを操作 */ }
971デフォルトの名無しさん:2010/01/27(水) 21:55:26
リストのつなぎ換えがしたくてこういうコードを書いたのですが
std::listのsplice関数ってこんな感じで自分自身に使っても大丈夫なんでしょうか
↓2番目と3番目の要素を交換するプログラム
typedef list<int> LI;
LI l;
for(int i=0;i<4;++i){l.push_back(i);}
LI::iterator i1=++l.begin();
LI::iterator i2=++(++l.begin());
l.splice(i1,l,i2);
copy(l.begin(),l.end(),ostream_iterator<int>(cout," "));
972デフォルトの名無しさん:2010/01/27(水) 22:05:48
>>959
あれ?リンカは賢くて必要にして十分なobjをリンクしてくれるものと思っていましたが、違いましたか。
973デフォルトの名無しさん:2010/01/27(水) 22:27:42
>>972
そういう環境もあるのかも知れない
974デフォルトの名無しさん:2010/01/27(水) 23:20:48
>972
良く読め。
「1個の.Cファイルをコンパイルしてobjを作り、それをlibにしたら」
975デフォルトの名無しさん:2010/01/28(木) 04:29:15
>>971 おk
976デフォルトの名無しさん:2010/01/28(木) 20:29:39
>>967
GetProcAddress(NULL, "func");
調べてみたところMSDNには書いてないけどこれでEXEから公開した関数にアクセスできるみたいですね
正しい使い方なのかわかりませんが・・・
977デフォルトの名無しさん:2010/01/28(木) 22:44:28
自前のスタティックライブラリを作成したのですが
やはりnamespaceを宣言しておいた方がいいのでしょうか?
978デフォルトの名無しさん:2010/01/28(木) 23:41:08
vector<class A> vec;で宣言したクラスAのメンバへのアクセスの仕方を教えてください
979デフォルトの名無しさん:2010/01/28(木) 23:43:53
vec[0].member
980デフォルトの名無しさん:2010/01/28(木) 23:47:35
>>978
まず、何らかのAをpush_backする。またはリサイズで確保する。
配列的なindexアクセスか、vectorのbackメンバで要素にアクセス。
ドット演算子でAのメンバにアクセス。

vec[0].A_Method();
vec.back().A_Method();

という流れじゃない?
981980:2010/01/28(木) 23:48:46
おっと、被った。
982デフォルトの名無しさん:2010/01/29(金) 00:00:21
>>979,980,981 さん
ありがとうございます.
983デフォルトの名無しさん:2010/01/29(金) 00:50:23
>>976
NULLの代わりにGetModuleHandle(NULL)を使えば心配要らない。
984デフォルトの名無しさん:2010/01/29(金) 01:40:09
>>977 それだけの情報じゃなんとも言えん。好きにしろ。
985デフォルトの名無しさん:2010/01/29(金) 09:27:41
Handle foo(void)
{
static my::AutoPtr<Handle> resource(Load("resource-name"), Rereaser);

return resource.get();
}

これってアプリ終了時にちゃんと開放してくれますかね?
986デフォルトの名無しさん:2010/01/29(金) 10:04:31
>>985
「ちゃんと開放」となるかどうかは知らないが、 resource のコンストラクタが成功すれば、
のデストラクタは main() 終了時や exit() 呼び出し時に呼び出されることになってる。

× rerease
○ release
987デフォルトの名無しさん:2010/01/29(金) 22:17:24
× 開放
○ 解放
988デフォルトの名無しさん:2010/01/29(金) 23:09:35
次スレ誰か頼む
989デフォルトの名無しさん:2010/01/29(金) 23:16:29
990デフォルトの名無しさん:2010/01/30(土) 02:28:42
そういえば昔
○開放
×解放
な現場があったな…占有してる「場所を開け放つ」んだから開放だとか…
えぇーって思ったけど
991デフォルトの名無しさん:2010/01/30(土) 08:52:49
あの娘を解き放て!
992デフォルトの名無しさん:2010/01/30(土) 12:23:39
あの娘は仮想メモリだぞ!
993デフォルトの名無しさん:2010/01/30(土) 13:51:20
元ネタなに?
994デフォルトの名無しさん:2010/01/30(土) 13:57:22
アシタカせっ記
995デフォルトの名無しさん:2010/01/30(土) 18:37:14
ウメハラがぁ!!
996デフォルトの名無しさん:2010/01/30(土) 18:38:37
捕まえてぇぇ!!!
997デフォルトの名無しさん:2010/01/30(土) 18:39:07
ばーすとよんで
998デフォルトの名無しさん:2010/01/30(土) 18:41:26
まだ入るぅぅ!!
999デフォルトの名無しさん:2010/01/30(土) 18:42:52
ウメハラがぁっ!!!!・・・つっ近づいてぇっ!!!
1000デフォルトの名無しさん:2010/01/30(土) 18:43:58
ウメハラがぁ決めたぁぁーっ!!!!
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。