memorandums

日々のメモです。

C言語で他ファイルから参照したければstaticはつけちゃダメよダメダメ(個人メモ)

サークルでシステム構築中の学生さんからプログラムについての相談があり、昨夜、一緒にごにょごにょやっていました。

こちらに赴任してからはoFでC++を触ることはあってもC言語はなかなか触る機会がなく。。。昔は仕事で使っていたのですが。。。忘れていました。悲しいですがしかたがありません。

とりあえず、逃げの方法でしのいでもらってのですが納得いかず。MacにVS2017をいれてC++環境を作り調べました。

まず、学生さんが持ち込んだ問題は以下。

  • main.cpp
#include "stdafx.h"

extern void a();

int main()
{
    a();
    return 0;
}
  • Source.cpp
#include "stdafx.h"

static void a() {
    printf("A");
}  

これをビルドすると以下のリンカーエラーが出ます。わかる人であればビルドする前にわかるんでしょうね。。。

f:id:ke_takahashi:20170622134913p:plain

a()が見えないというエラーです。その学生さんも私もLNK2019でぐぐったりしてみたわけですが、外部DLLを使用するネタとか、また、extern "C"をつけろというメモとかありまして。。。どれも対策にはならなかったんですね。

関数a() にstaticキーワードをつけているわけですが、C言語では見慣れないキーワードではありませんし、スコープの意識が高いんだな。。。くらいに見過ごしていました。

関数a() を使用するmain.cppではextern宣言していますのでリンクできるはずだ、という思い込みもありました。また、学生さんが持ち込んだソースには他に似たような関数があり、それはリンクに成功していることも盲点になったのかと思います。

結論は、このstaticキーワードがダメ、ということです。staticキーワードをつけることによって、グローバル変数や関数がそのファイル中のみ参照できるようにすることができます。これをファイルスコープというそうで。オブジェクト指向言語カプセル化と同じ効果があります。

ファイルスコープはコンパイル時だけではなく、リンク時にも有効ということがわかっていなかった。。。のだと思います。そりゃそうですね。せっかくファイルスコープで宣言した識別子がリンク時に参照できてしまうなら意味ないですものね。。。

手元に昨日、学生さんが持ち込んだソースがないので解決方法として有効だったかわかりませんが、staticを削除して他ファイルのソースに公開することを宣言すればリンクエラーはなくなります。私の理解の中では当然の結果と思います。

  • Source.cpp
#include "stdafx.h"

void a() {
    printf("A");
}  

すぐに忘れてしまいそうなので、とりあえずメモしておきたいと思います。公開したい関数にはstaticはつけない、他ファイルのソースに非公開にしたい関数にはstaticをつける、ですね。

上記について、間違いがありましたらお手数ですがご指摘いただけると幸いです。

ホワイトボードシート

ゼミ室にはホワイトボードがあるのですが配置上、使いにくいところにありまして。。。一方で壁が空いているのでなんかいい方法がないかと考えてきました。

できればGoogleのオフィスみたいに壁面全面をホワイトボードにできたらな。。。とも。

これは必見!Google帝国の壮大なマスタープラン! | POP*POP

探してみた結果、以下がいいようでしたので今年の予算で導入しようと発注しました。

item.rakuten.co.jp

厚さ0.2mm、高さ900mm、長さ3mを発注しました。

ちょうどゼミをやっているときに納品されたので、学生に手伝ってもらって設置しました。設置した様子が以下です。

f:id:ke_takahashi:20170614133215j:plain

簡単とは言い難いですが、素人の大人4人で貼れました。3人がシートを持って、1人が裏シートの剥がし役をしました。試行錯誤すること10分くらいでしょうか。

マグネットがつけられます。書いた感じも普通のホワイトボードと同じでした。

壁にシールを貼った感じになりますので、剥がすとどうなるかは。。。わかりませんが。学校ですので用途はあると思います。

あとは耐久性ですね。。。これは使い続けてみないとなんとも言えません。意外としっかりしているのでもつと思いますが。

はい、とりあえず。

つくると、娘と遊んできました。

ツイッターで知ったファブ系イベント。

vol3.tsukuruto.net

今回で3回目とか。

まさに灯台下暗しです。

小学生の娘と二人で九大大橋キャンパスまで行ってきました。

詳しくは、上のホームページに出展者の情報がありますのでそちらをどうぞ。

全体の雰囲気はこんな感じでした。小さいですが。。。個人情報的にまずいので雰囲気だけ。

f:id:ke_takahashi:20170612232213p:plain

九州各地からファブな方が集まっていました。

展示とあわせてトークショーやシンポジウムやセミナーなどが混在していてとても賑やかなイベントでした。

実用性を追求したもの、(良い意味で)おバカな作品、精密な物、可愛いもの、個人やベンチャーやファブラボや。

いろいろな人がいる一方で、ものづくりが好きというキーワードで繋がっている感じがしました。

娘もたくさん楽しませてもらい、結局、2時間以上うろついていたように思います(笑)

福岡市立科学館も秋にはリニューアルします、ということも話されていました。

www.fukuokacity-kagakukan.jp

メイカーな人といろいろとお話させていただき「何か作るぞー」というエネルギーをもらいました。

次回があったらぜひ出展したいですね。

MacのACアダプターが断線した → とりあえず修理

MBAを充電しようと自宅に常備しているACアダプターを繋いたものの充電中ランプが点灯しません。

最近、MBAのバッテリーを交換して調子悪かったのでMBAのせいかと思いましたが、他のMacを繋いでも充電中ランプは点灯せず。どうやらACアダプタ自体がいかれているようです。

ふと、アダプタをみると以下のような感じ。。。どうやら断線しているようです。

f:id:ke_takahashi:20170610195343j:plain

このために大学に行くのはちょっと大変。この土日にもPCで作業したいので。。。とりあえず土日だけでもこのアダプタでやり過ごしたいと思いました。

ぐぐってみると修理した先人がいました。

zigsow.jp

ちょうど天神にいく用事があったので、スミチューブを買ってきました。

さあ、上記にしたがって分解しようとしたのですが、外ケースがなかなか取れない。。。マイナスドライバーを差し込んで無理にやることもできなくはないですが怪我しそうなので、ネジで簡易的なものを作って分解できました。

f:id:ke_takahashi:20170610111659j:plain

分解の様子を子供にとってもらいました。以下です。手が3本あったらね。。。

youtu.be

スミチューブを忘れずに差し込んで、被覆を剥いて。。。あれ?半田ごてがない。。。あるはずの。

ここで中断して、近所のお店をまわって半田ごてを探しましたが。。。残念ながらありませんでした。

しかたがなく、またまたYouTubeで半田ごての代用品がないか確認するとライターが使えるとか。針金もなかったのでゼムクリップを伸ばして作りました。

f:id:ke_takahashi:20170610182025j:plain

ただ、これではハンダは確かに溶けるのですが、電線には熱が伝わらないため溶け出しません。。。結局、ライターの火をそのままつけて半田付けしました。ただ、この方法だとスミチューブが熱収縮してしまい。。。使い物になりませんでした。。。orz しかたがなくビニールテープで絶縁しました。(

半田ごてのありがたみがよくわかりました。

とりあえず、MBAを充電できました。決して安全ではないしいつ出火するかもしれません。見ているときだけ使っています。来週、研究室でもう一度半田付けしなおします。

以上です。

上記は、あくまで緊急の方法です。かなり危険な工程もあります。あくまで自己責任でお願いします。

JSPのエラーにはまること3時間

金曜日の4、5限目に講義と演習を担当しています。

これまでは水曜日の昼間だったのですが。。。カリキュラム改定の影響で時間割が見直しになり。。。

まさに一週間を締めくくるような授業です。

この授業を終えたあとに、前回分の模範解答を作ろうと自分の部屋でやっていたんですね。

その過程で以下のエラーに出くわしました。

f:id:ke_takahashi:20170609233320p:plain

エラーメッセージは「Syntax error on token ")", delete this token」でした。

対応するかっこがないのかと思えばありますし。被害者なのかと知る限りの様々な方法で原因を追跡していたのですが、どうしてもわかりませんでした。。。こんなの久しぶりでした。

時間も時間だったので帰路につき、電車内でも続きをやっていたのですが、やはりわからず。。。

何気なしに39行目の終わりでエンターキーを押してみると以下のように。

f:id:ke_takahashi:20170609233621p:plain

なんと。。。エディタの見えない右端の方に ); があったんですね。。。どうやって入ったかは詳しくは書きませんが、MBAのキーボードのうえに物がのったときにキーがリピートしていたのは見ました。たぶんそのときだったと思います。

エラーメッセージは正しかったわけです。

人間、思い込み(どうせエラーメッセージなんて正しいわけがない、あくまで間接的な情報だ)が悪さをしたのでした。

「エラーメッセージをよく読めよ」と学生さんには言っているのですが、自分にも言えたわけです。はい。

部品・工具整理、その後

先月、こんなエントリーを書きました。

memorandums.hatenablog.com

こんなのみて何が楽しいか。。。と思われるかもしれませんが。。。

やっとラックが納品されました。ずいぶんかかったなぁ。。。楽天で買えば1週間以内に届いていたでしょう。しかたがありません。

タカハシさんの開発部屋に憧れて、ちょっと真似してみました。とりあえず収納ケースに入った資材や部品やマイコンや工具などを収納しました。

f:id:ke_takahashi:20170609005103j:plain

3Dプリンタも入れたし、レーザーカッターもある。環境はほぼ整いました。

あとはアイデアと時間だな。。。それを言っちゃおしまいですね。

さあ、やるぞー。

Processingのlibrariesとmodesが肥大したのでstatic linkにしてよかったよ、という話

■2017/6/10追記
ここからーーーーーーーーーーーー
以下のエントリーを書いて、めでたしと思っていたのですが。。。Dcopboxの容量をみると全く変わっていないことに気づきました。

調べると、ln -sしたフォルダーをDropboxが(も)追跡してくれて、その先のフォルダーの内容もDropboxに同期してくれていたんですね。。。ln -sの意味は全くありません。。。Processingが追跡できるならDropboxアプリも追跡できるはずです。浅はかでした。

とにかくクラウドに同期してあちこちから取り出したいのは自作したソースだけです。

発想を逆転させて、Processingのフォルダ全体をDropboxフォルダにいれるのではなく、Processingのフォルダを別のところにおき、スケッチのstatic linkをDropboxにおけば、追跡して同期してくれるはずです。

ただ、自作のスケッチ群は以下のようなフォルダ構成になっていて、まじめにやるとスケッチを追加するごとにそのリンクをDropboxに登録する必要が出てきます。そんなの嫌ですから。。。以下の変更後のようにして自作スケッチをいれるフォルダを作りその中にスケッチをいれて、その親フォルダ(processing_src)のリンクをDropboxに入れました。

とりあえず、これでDropboxに同期されること、あとはProcesingで動作することを確認しています。スケッチとlibrariesやmodesをいれる場所は分離できるはずなので、たぶん問題はないはずです。

■オリジナル
ーProcessing
ーーmodes
ーーlibraries
ーー自作スケッチ1
ーー自作スケッチ2
ーー自作スケッチ3
   ・
   ・

■変更後
ーProcessing
ーーmodes
ーーlibraries
ーーprocessing_src
ーーー自作スケッチ1
ーーー自作スケッチ2
ーーー自作スケッチ3
   ・
   ・

ここまでーーーーーーーーーーーー



講義資料や論文や開発中のソースコードなどをDropboxにいれてあちこちで仕事ができるようにしています。成績など個人情報はローカルで管理しています。

昨夜、Dropboxから残容量がわずかですとの警告がきました。

無料アカウントで使わせていただいているのでお金を出せばいいのでしょうけど、その前に占有しているファイルはなにか確認してみました。

するとProcessingのmodeとlibrariesで3GBになるとのこと。

とりあえず、ソースコードだけGoogle Driveで管理すればいいんじゃないかと昨夜に移動して同期開始したのですが、朝みても終わっていなくて。。。そういえば過去にもこんなことがあって移行を考えたけどDropboxの方が早くてやめたんでした。

もう一度考えなおしまして、そもそも、modeとlibrariesは自分が開発したものではありませんのでDropboxで同期する必要はありません。同期から外してしまえばいいんじゃないかと。スタティックリンク(ln -s)を使いました。

その後、Processingを起動して動作確認しましたが、問題ありませんでした。

ちなみにln -sではなくMacのショートカットでできないかとやってみたのですがダメでした。Windowsにはスタティックリンクはないと思いますので。。。どうするんだろう?

もし、同様のことでお困りの方はお試しを。