ラベル Windows の投稿を表示しています。 すべての投稿を表示
ラベル Windows の投稿を表示しています。 すべての投稿を表示

2010年12月20日月曜日

「VC 2010 Expressでx64コンパイル」を見つけて嬉しかったのでメモ

VC 2010 Expressでx64コンパイル(How to compile x64 app with VC 2010 Express)
mnemotoさんありがとう
<?xml version=”1.0″ encoding=”utf-8″?>
<Project DefaultTargets=”Build” ToolsVersion=”4.0″ xmlns=”http://schemas.microsoft.com/developer/msbuild/2003“>
  <PropertyGroup>
    <SourcePath>$(SourcePath)</SourcePath>
    <IntDir>$(SolutionDir)$(Platform)\$(Configuration)\</IntDir>
    <IncludePath>C:\Program Files\Microsoft SDKs\Windows\v7.1\Include;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include</IncludePath>
    <LibraryPath>C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\x64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64</LibraryPath>
   
    <TrackFileAccess>false</TrackFileAccess>
  </PropertyGroup>
</Project>
set “PATH=%PATH%;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64″
set “INCLUDE=C:\Program Files\Microsoft SDKs\Windows\v7.1\Include;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include”
set “LIB=C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\x64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64″
bjam release debug threading=multi link=static runtime-link=static toolset=msvc address-model=64

2010年4月17日土曜日

Xperia X10とWindows 7 64bit の USBドライバ(SDKのドライバをロードする方法)

android_winusb.infを修正しておくだけ。


android_winusb.inf.patch
--- android_winusb.inf.orig     2010-04-17 22:36:28.789163200 +0900
+++ android_winusb.inf  2010-04-17 23:24:14.522073700 +0900
@@ -26,6 +26,9 @@
 %ProviderName% = Google, NTx86, NTamd64

 [Google.NTx86]
+; Xperia X10
+%SingleAdbInterface%        = USB_Install, USB\VID_0FCE&PID_D12E
+%CompositeAdbInterface%     = USB_Install, USB\VID_0FCE&PID_D12E&MI_01
 ; HTC Dream
 %SingleAdbInterface%        = USB_Install, USB\VID_0BB4&PID_0C01
 %CompositeAdbInterface%     = USB_Install, USB\VID_0BB4&PID_0C02&MI_01
@@ -44,6 +47,9 @@
 %CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_4E12&MI_01

 [Google.NTamd64]
+; Xperia X10
+%SingleAdbInterface%        = USB_Install, USB\VID_0FCE&PID_D12E
+%CompositeAdbInterface%     = USB_Install, USB\VID_0FCE&PID_D12E&MI_01
 ; HTC Dream
 %SingleAdbInterface%        = USB_Install, USB\VID_0BB4&PID_0C01
 %CompositeAdbInterface%     = USB_Install, USB\VID_0BB4&PID_0C02&MI_01

2010年3月24日水曜日

MinGWでgdbmをビルドしてみた

flockとかfsyncがなくてダメな感じ。

systems.h
#include <io.h>
#include <windows.h>

#define UNLOCK_FILE(dbf) {                              \
    HANDLE h = (HANDLE)_get_osfhandle(dbf->desc);       \
    if (INVALID_HANDLE_VALUE != h) {                    \
      UnlockFile(h, 0, 0, (DWORD)-1, (DWORD)-1);        \
    }                                                   \
  }

#define READLOCK_FILE(dbf) {                                            \
    HANDLE h = (HANDLE)_get_osfhandle(dbf->desc);                       \
    if (INVALID_HANDLE_VALUE == h) {                                    \
      lock_val = -1;                                                    \
    } else {                                                            \
      OVERLAPPED over;                                                  \
      ZeroMemory(&over, sizeof(over));                                  \
      DWORD flags = LOCKFILE_FAIL_IMMEDIATELY;                          \
      if (!LockFileEx(h, flags, 0, (DWORD)-1, (DWORD)-1, &over)) {      \
        lock_val = -1;                                                  \
      } else {                                                          \
        lock_val = 0;                                                   \
      }                                                                 \
    }                                                                   \
  }

#define WRITELOCK_FILE(dbf) {                                           \
    HANDLE h = (HANDLE)_get_osfhandle(dbf->desc);                       \
    if (INVALID_HANDLE_VALUE == h) {                                    \
      lock_val = -1;                                                    \
    } else {                                                            \
      OVERLAPPED over;                                                  \
      ZeroMemory(&over, sizeof(over));                                  \
      DWORD flags = LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK; \
      if (!LockFileEx(h, flags, 0, (DWORD)-1, (DWORD)-1, &over)) {      \
        lock_val = -1;                                                  \
      } else {                                                          \
        lock_val = 0;                                                   \
      }                                                                 \
    }                                                                   \
  }

2010年3月11日木曜日

MinGWでDLLを作ってみる (32bitと64bit)

手軽な方法はこれ。

$ g++ -static -shared -o hello.dll hello.cc world.cc -Wl,--out-implib,libhello.a

gcc 4.4.0 (32bit)を使って、上記の方法でDLLをつくると、必要以上に多くの関数をexportしちゃっている。

ちゃんとDEFファイルを用意して必要な関数だけをexportする場合は次のようにすればよいみたい。

$ g++ -c hello.cc
$ g++ -c world.cc
$ g++ -mdll -o hello.dll.tmp -Wl,--base-file,hello.dll.base hello.o world.o
$ dlltool -l libhello.a --dllname hello.dll --base-file hello.dll.base --output-exp hello.dll.exp --def hello.def
$ g++ -mdll -o hello.dll -Wl,hello.dll.exp -static hello.o world.o

MinGW-w64でx64バイナリを作ってみる

MinGW-w64からmingw-w64-bin_i686-mingw_20100310.zipをダウンロード

適当な場所に展開してPATHを通してコンパイル。

$ x86_64-w64-mingw32-g++ Hello.cpp -static

※ -staticオプションを指定しないと LIBSTDC++-6.DLL が必要。

MinGW/g++-4.4.0でコンパイルしてみた

「-static-libgcc」これをつけると、libgcc_s_dw2-1.dllを配布しなくてすむ

コンソール
$ g++ --version
g++.exe (GCC) 4.4.0
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ls -l Hello.cpp
-rw-r--r-- 1 takumakei Administrators 97 Mar 11 13:00 Hello.cpp

$ cat Hello.cpp
#include 

int main() {
  std::cout << "Hello world" << std::endl;
  return 0;
}

$ g++ -o Hello -O3 Hello.cpp -static-libgcc

$ ls -l Hello.exe
-rwxr-xr-x 1 takumakei Administrators 3862265 Mar 11 13:56 Hello.exe*

$ strip Hello.exe

$ ls -l Hello.exe
-rwxr-xr-x 1 takumakei Administrators 496142 Mar 11 13:56 Hello.exe*

$ ./Hello.exe
Hello world
ウィンドウ
$ ls -l HelloW.cpp
-rw-r--r-- 1 JP10007 Administrators 150 Mar 11 13:34 HelloW.cpp

$ cat HelloW.cpp
#include 

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPTSTR, int) {
  MessageBox(NULL, "Hello world", "HelloW", MB_OK);
  return 0;
}

$ g++ -o HelloW.exe -O3 HelloW.cpp -static-libgcc -mwindows

$ ls -l HelloW.exe
-rwxr-xr-x 1 JP10007 Administrators 334435 Mar 11 13:59 HelloW.exe*

$ strip HelloW.exe

$ ls -l HelloW.exe
-rwxr-xr-x 1 JP10007 Administrators 75790 Mar 11 13:59 HelloW.exe*

2010年2月4日木曜日

swfmillのバッチファイルを作ってみた

swfmillを使ってswfとxmlを相互に変換する作業を
繰り返し繰り返しやる必要があったので
ドラッグアンドドロップできるようなバッチファイルを作ってみた。

swf2xml.bat
@ECHO OFF
FOR %%I IN ( %* ) DO (
  ECHO $ swfmill swf2xml %%~nxI %%~nI.xml
  swfmill swf2xml "%%~I" "%%~dpnI.xml"
  ECHO .
)
PAUSE
xml2swf.bat
@ECHO OFF
FOR %%I IN ( %* ) DO (
  ECHO $ swfmill xml2swf %%~nxI %%~nI.swf
  swfmill xml2swf "%%~I" "%%~dpnI.swf"
  ECHO .
)
PAUSE

2009年7月17日金曜日

Rubyの拡張モジュールでリソースを解放する方法

RubyはGCを持っているので、Rubyの世界の中ではリソースの解放をそれほど気にしなくてもよいけれど、Cで記述したRubyの拡張モジュールではそうはいかない。

インスタンス生成で資源を確保し、GCがインスタンスを回収した時に資源を解放するサンプル。

foo.c
#include <ruby.h>
#include <rubysig.h>

static VALUE g_cFoo = Qnil;

struct FooData
{
int x;
int y;
};

static void
Foo_free_data(struct FooData* data)
{
fprintf(stderr, "free 0x%08x\n", data);
#if defined(USE_RUBY_XMALLOC)
ruby_xfree(data);
#else
free(data);
#endif
}

static VALUE
Foo_alloc_data(VALUE self)
{
return Data_Wrap_Struct(self, 0, &Foo_free_data, 0);
}

static struct FooData*
Foo_data(VALUE self)
{
struct FooData* sval = NULL;
Data_Get_Struct(self, struct FooData, sval);
return sval;
}

static VALUE
Foo_initialize(VALUE self)
{
#if defined(USE_RUBY_XMALLOC)
DATA_PTR(self) = ruby_xmalloc(sizeof(struct FooData));
#else
DATA_PTR(self) = malloc(sizeof(struct FooData));
#endif
fprintf(stderr, "alloc 0x%08x\n", DATA_PTR(self));
return self;
}

Init_foo()
{
g_cFoo = rb_define_class("Foo", rb_cObject);

rb_define_alloc_func(g_cFoo, &Foo_alloc_data);
rb_define_method(g_cFoo, "initialize", &Foo_initialize, 0);
}

※注意!このモジュールを使って ruby 1.8.7 p174 {mingw32|linux}で ruby -rfoo -e 'loop{Foo.new}' したら Segmentation faultになった。原因不明>_<

2009年5月26日火曜日

静的にリンクしたDLLのフック

ちょっとはまった。
  1. フック対象のTARGET.DLLのファイル名をORIGINAL.DLLに変更する。
  2. 新しくTARGET.DLLを作り、ORIGINAL.DLLをLoadLibraryとGetProcAddressで元のコードを呼ぶ。
たまたま(!?)、DLLからは関数だけをEXPORTする村に住んでいるので、この手順でいけるだろうと思っていたのだが甘かった。

「ORIGINAL.DLLがEXPORTする関数を呼び出すデストラクタ」をもつオブジェクトをグローバル変数としてインスタンス化してあって、そのデストラクタが呼ばれる前にORIGINAL.DLLが解放されていた。

参考: Why are DLLs unloaded in the "wrong" order? (なぜDLLは意図しない順序でアンロードされるのか?)

解決策を探している間にみつけたMemoryModuleも面白そうだったけれど、
依存関係情報を与えるためには解決策は静的リンクにするしかなさそうだ・・・

TARGET.DLLから名前を変えられてしまったORIGINAL.DLLのインポートライブラリは、モジュール定義ファイルから簡単に生成できる。

LIB /DEF:ORIGINAL.def /MACHINE:X86 /out:ORIGINAL.lib

あとは、ORIGINAL.libを静的リンクした新しいTARGET.DLLを作ればよい。
しかし、ORIGINAL.libに含まれる関数を、新しいTARGET.DLLにも定義しなければ意味がないのに、定義してしまうと今度は名前が衝突してリンカが文句を言うだろう。その前にコンパイラが混乱するか・・。

なので、結論は

TARGET.DLL → ALIAS.DLL → ORIGINAL.DLL

このように静的リンクすること。

・・・かも-.-;

target.c
#include "alias.h"

#pragma comment(lib, "alias")

int target_function_name()
{
return alias_function_name();
}
alias.c
#include "target.h"

#pragma comment(lib, "original")

int alias_function_name()
{
return target_function_name();
}

2009年5月1日金曜日

windowsでlibeventしてみた

前から使ってみたいと思っていたlibevent。ようやく試してみる機会があった。

ん~。

当然IOCP対応してるんだろーと思ったらlibevent-1.4.10-stableでは未対応なのね...

libevent-2.0.1-alphaWhat's newにはIOCPに対応始めたみたいなことが書いてある。

vc90でビルドするのも一手間必要。

なんとかregressにパスするバイナリ作れたのでテストコード。

evhttpd.cc
#include <stdio.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>

#include <event.h>
#include <evhttp.h>

#pragma comment(lib, "ws2_32")

struct EnableWinsock
{
EnableWinsock(){
WSADATA wsaData;
const int r = WSAStartup(MAKEWORD(2, 2), &wsaData);
}
~EnableWinsock(){
WSACleanup();
}
};

void root_handler(evhttp_request* req, void* arg)
{
evbuffer* buf = evbuffer_new();
if(!buf){
puts("failed to create response buffer");
return;
}

evbuffer_add_printf(buf, "Hello: %s\n", evhttp_request_uri(req));
evhttp_send_reply(req, HTTP_OK, "OK", buf);
}

void generic_handler(evhttp_request* req, void* arg)
{
evbuffer* buf = evbuffer_new();
if(!buf){
puts("failed to create response buffer");
return;
}

evbuffer_add_printf(buf, "Requested: %s\n", evhttp_request_uri(req));
evhttp_send_reply(req, HTTP_OK, "OK", buf);
}

int wmain(int argc, wchar_t* argv[])
{
EnableWinsock enableWinsock;

event_init();

evhttp* httpd = evhttp_start("0.0.0.0", 8880);
if(!httpd){ return 1; }

evhttp_set_cb(httpd, "/", root_handler, NULL);
evhttp_set_gencb(httpd, generic_handler, NULL);

event_dispatch();

evhttp_free(httpd);

return 0;
}

2009年4月30日木曜日

DLLからDEFファイルを作る

DLLファイルからDEFファイルを自動生成する必要があって、MinGWのpexportsを持っていなかったので、さくっと書いてみた。

dll_to_def.rb
#!ruby -Ku
# Generate the .def file from .dll using 'dumpbin.exe'
# 2009-04-30 23:43:20

class ExportsList
FUNCTION_LINE_PATTERN = /^\s+(\d+)\s+[0-9A-Fa-f]+\s+[0-9A-Fa-f]+\s+(.*)$/

def initialize(dllname)
@dllname = dllname
@max_name_length = 0
@exports = []
dumpbin(dllname) do |line|
next unless line =~ FUNCTION_LINE_PATTERN
@exports << [$1, $2]
@max_name_length = $2.length if @max_name_length < $2.length
end
end

def save_as_def
width = ((@max_name_length + 7) / 8) * 8
basename = File.basename(@dllname, '.dll')
File.open(basename + '.def', 'w') do |f|
f.puts(%Q|LIBRARY "#{basename}"|)
f.puts
f.puts('EXPORTS')
@exports.each do |i, name|
f.print("\t#{name}")
f.print("\t" * ((width + 7 - name.length) / 8))
f.puts("@#{i}")
end
end
end

private
def dumpbin(dllname)
raise "Command not found: dumpbin" unless cmd_exist?('dumpbin')
Kernel.open("|dumpbin /exports #{dllname}") do |f|
while line = f.gets
yield(line)
end
end
end

def cmd_exist?(cmd)
ENV['PATH'].split(';').each do |path|
(';' + ENV['PATHEXT']).split(';').each do |ext|
pathname = File.join(File.expand_path(path), cmd + ext)
return true if File.exist?(pathname)
end
end
nil
end
end

if $0 == __FILE__
ARGV.each do |dllname|
ExportsList.new(dllname).save_as_def
end
end

2009年4月28日火曜日

コマンドプロンプトでファイルを探す(リファクタリング)

コマンドプロンプトでファイルを探すをリファクタリング。
少しだけシンプルになったと思う。
locate.rb
#!ruby -Ku

module Locate
EXCLUDE_PATTERN = /^(\.|\.\.|\.svn)$/i

module_function
def locate(dirname, patterns)
each_entries(dirname) do |pathname, filename|
if File.directory?(pathname)
puts(pathname + '/') if match?(filename, patterns)
locate(pathname, patterns)
else
puts(pathname) if match?(filename, patterns)
end
end
end

def each_entries(dirname)
entries(dirname).each do |filename|
pathname = (dirname == '.' ? filename : File.join(dirname, filename))
yield(pathname, filename)
end
end

def entries(pathname)
Dir.entries(pathname).select do |filename|
filename !~ EXCLUDE_PATTERN
end
end

def match?(filename, patterns)
patterns.each do |pattern|
return true if filename =~ pattern
end
return false
end
end

if $0 == __FILE__
Locate.locate('.', ARGV.map{|pattern|Regexp.new(pattern, Regexp::IGNORECASE)})
end

2009年4月22日水曜日

WindowsでもC++のプログラムのデバッグを楽にしたいなぁ

C++のプログラムのデバッグを楽にする方法はとっても便利そう。

でもLinuxだったらgccで-gつけてコンパイルするのが基本だし。実行時のデメリットがほとんどないから。
スタックトレースできる機能はもともとあったよね。

WindowsでもC++でスタックトレースを表示してから落ちてほしいよなぁ。

最近そういう(すぐ落ちる)プログラムを毎日見てる。

2009年4月19日日曜日

NTEmacs 22BASE をインストール

自宅のマシンのEmacsは、公式サイトからダウンロードした22.3だったのだが、IMEパッチが適用されていないので不便だった。

普段使っている.emacsもロードできず、キーバインドになれていなくて用途が限られていた。

ようやく日本語インライン変換パッチ適用済みバージョンに差し替えたので、ついでに.emacsも書き換えてみた。
.emacs.el
;; [2009-04-19 01:25:04]

(setq inhibit-startup-message t)

(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(display-time-mode t)
'(current-language-environment "Japanese")
'(tool-bar-mode nil)
'(line-number-mode t)
'(column-number-mode t)
'(show-paren-mode t)
'(transient-mark-mode t))

(fixed-width-set-fontset "msgothic" 14)

(setq default-frame-alist
(append '((foreground-color . "black")
(background-color . "LemonChiffon")
(border-color . "black")
(mouse-color . "white")
(cursor-color . "black")
(top . 0)
(left . 1040)
(width . 96)
(height . 77)
(line-spacing . 0)
(cursor-type . box))
default-frame-alist))

(setq-default tab-width 4 indent-tabs-mode nil)

;;(add-hook 'c++-mode-hook
;; '(lambda()
;; (c-set-style "cc-mode")
;; (c-set-offset 'innamespace 0)))

(defconst my-c-style
'((c-tab-always-indent . t)
(c-comment-only-line-offset . 4)
(c-hanging-braces-alist . ((substatement-open after)
(brace-list-open)))
(c-hanging-colons-alist . ((member-init-intro before)
(inher-intro)
(case-label after)
(label after)
(access-label after)))
(c-cleanup-list . (scope-operator
empty-defun-braces
defun-close-semi))
(c-offsets-alist . ((arglist-close . c-lineup-arglist)
(substatement-open . 0)
(case-label . 4)
(block-open . 0)
(innamespace . 0)
(knr-argdecl-intro . -)))
(c-echo-syntactic-information-p . t))
"My C Programming Style")

;; offset customizations not in my-c-style
(setq c-offsets-alist '((member-init-intro . ++)))

;; Customizations for all modes in CC Mode.
(defun my-c-mode-common-hook ()
;; add my personal style and set it for the current buffer
(c-add-style "PERSONAL" my-c-style t)
;; other customizations
(setq tab-width 8
;; this will make sure spaces are used instead of tabs
indent-tabs-mode nil)
;; we like auto-newline and hungry-delete
(c-toggle-auto-hungry-state 1)
;; key bindings for all supported languages. We can put these in
;; c-mode-base-map because c-mode-map, c++-mode-map, objc-mode-map,
;; java-mode-map, idl-mode-map, and pike-mode-map inherit from it.
(define-key c-mode-base-map "\C-m" 'c-context-line-break))

(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

;;;; IME

(mw32-ime-initialize)
(setq default-input-method "MW32-IME")
(setq-default mw32-ime-mode-line-state-indicator "[--]")
(setq mw32-ime-mode-line-state-indicator-list '("[--]" "[あ]" "[--]"))
;; y/n, yes/no の問い合わせ時に IME をオフにする
(wrap-function-to-control-ime 'y-or-n-p nil nil)
(wrap-function-to-control-ime 'yes-or-no-p nil nil)

;;;; TAKUMAKEI

(defun kei-scroll-up ()
(interactive)
(scroll-up 1))

(defun kei-scroll-down ()
(interactive)
(scroll-down 1))

(defun kei-line-up ()
(interactive)
(let ((save-marker (point-marker)))
(kill-region (line-end-position) (point-marker))
(previous-line)
(yank)
(kill-region (line-end-position) (point-marker))
(goto-char (marker-position save-marker))
(yank '(nil))
(previous-line)))

(defun kei-line-down ()
(interactive)
(let ((save-marker (point-marker)))
(kill-region (line-end-position) (point-marker))
(next-line)
(yank)
(kill-region (line-end-position) (point-marker))
(goto-char (marker-position save-marker))
(yank '(nil))
(next-line)))

(load-library "time-stamp")
(defun kei-insert-date-string ()
(interactive)
(insert
(format "[%s %s]"
(time-stamp-yyyy-mm-dd)
(time-stamp-hh:mm:ss))))

(defun kei-load-memo (df)
(find-file
(expand-file-name
((lambda (today)
(format
"c:/Users/kei/Documents/memo/%s/%s(%s).txt"
(format-time-string "%Y" today)
(format-time-string "%Y-%m-%d" today)
(aref [ "日" "月" "火" "水" "木" "金" "土" ]
(string-to-number (format-time-string "%w" today)))))
((lambda (ts)
(let ((dt (decode-time ts)))
(encode-time 0 0 0
(+ (car (nthcdr 3 dt)) df)
(car (nthcdr 4 dt))
(car (nthcdr 5 dt)))))
(current-time))))))

(defun memo ()
(interactive)
(kei-load-memo 0))

(defun memox ()
(interactive)
(kei-load-memo (read-minibuffer "何日後?> " "")))

(defun kei-set-alpha1 ()
(interactive)
(set-alpha '(100 100)))

(defun kei-set-alpha2 ()
(interactive)
(set-alpha '(50 50)))

(defun kei-set-alpha3 ()
(interactive)
(set-alpha '(20 20)))

(global-set-key [(meta d)] 'kei-insert-date-string)
(global-set-key [(meta n)] 'kei-scroll-up)
(global-set-key [(meta p)] 'kei-scroll-down)
(global-set-key [(meta up)] 'kei-line-up)
(global-set-key [(meta down)] 'kei-line-down)
(global-set-key [(meta g)] 'goto-line)
(global-set-key [(meta o)] 'open-line)
(global-set-key [(ctrl h)] 'backward-delete-char-untabify)
(global-set-key [(ctrl o)] 'toggle-input-method)
(global-set-key [(ctrl \\)] 'kei-set-alpha1)
(global-set-key [(ctrl ,)] 'kei-set-alpha2)
(global-set-key [(ctrl .)] 'kei-set-alpha3)

2009年4月18日土曜日

コマンドプロンプトでファイルを探す

ファイル名でファイルを検索することがよくある。
特にコマンドプロンプトを使っているときにそういう場面に遭遇する。
その都度Explorerを開いて作業するのは不便なのでRubyで作ってみた。
locate.rb
#!ruby -Ku

def handle_file(names, name)
basename = File.basename(name)
found = false
names.each do |target|
if basename =~ target
found = true
break
end
end
puts name if found
end

def handle_dir(names, name)
handle_file(names, name + '/')
handle_all(names, name + '/*')
end

def handle_all(names, name)
Dir[name].each do |candidate|
if File.directory?(candidate)
basename = File.basename(candidate)
handle_dir(names, candidate) unless basename == '.' || basename == '..'
else
handle_file(names, candidate)
end
end
end

def locate(names)
names = names.map{|n| Regexp.new(n)}
handle_all(names, '.*')
handle_all(names, '*')
end

if $0 == __FILE__
locate(ARGV)
end

2009年4月15日水曜日

boostproが登録制になってた

自分一人で使うなら、ソースコードからビルドして使っていれば十分なのだけど、チームで共同開発する場合には、「ソースコードからビルド・・・」なんて言おうものなら、「そんなもの使うなめんどくさい」と言われてしまう可能性が高い。

そんなときにwww.boostpro.comが便利だったのに・・・

いつのまにか、アカウント登録しないとダウンロードさせてもらえなくなってる。
「登録するのめんどくさい」って言われてしまうだろうなぁ。

しかも、ネットワークインストールになってる。
これだと、リンク先が突然なくなってしまわないかと不安で夜も眠れないよなぁ。

2009年4月14日火曜日

関数の呼び出し規約に縛られないラッパーDLLを作る

関数の呼び出し規約に縛られないラッパーDLLを作る

これは面白い!
なにかの時に役に立ちそう。

「特攻する別exeを作って生き残った方で呼び出す(笑)」ここは何度読んでも笑える。

要点は
  • インラインアセンブラで自前でスタック調整
  • コンパイルオプションなどによっては、最適化されてしまってまずい事になるのを予防する
という2点。

スタック調整
unsigned long reg_esp;
asm { mov reg_esp, esp }
// 関数呼び出し
asm { mov esp, reg_esp }

詳しいことは元ネタを参照。

「問題ある部分をDLLとして切り分ける」ことが、なぜ「最適化でまずいことになるのを予防する」につながるのかな?

「切り分けしたDLLが問題ないことがわかったらリビルドはしないで使い回すことができる」から?

MigemizeExplorer

エクスプローラを日本語でインクリメンタルサーチできるのだそうだ。
すごい!便利~!

...なのだろうけど...

こういう機能はデフォルトでついていて欲しかった。

Windowsをカスタマイズしまくってめちゃくちゃ使いやすくなってしまうと、他の環境に引っ越しする時に面倒なことになったり、たまたま使わなくちゃいけないWindowsとかを使う時に、あれ?あれ?って驚いてしまう。

Explorerは特に使用頻度が高いだけにたちが悪い。

それにフォルダ名の命名規則(と言うほど大げさなものではないが)がなんとなくできていて、検索対象にしそうなフォルダ名の先頭には日本語を使わないように馴らされているので、インストールはしないかもな。

もう少し若い頃に出会えていれば良かったね。

.DEFでNONAMEしたら関数名は見えないよ

早とちりした。「.DEFでNONAMEしても関数名見えちゃうじゃん」は嘘だった。
ビルドした場所に.PDBが存在していたから関数名も「親切に」教えてくれたのだった。

DLLをビルドする時に、「リンカ→デバッグ→デバッグ情報の生成」を「いいえ」にしたら、dumpbinの出力に元の関数名が表示されることはなかった。

良かった。恥ずかしい関数名でもばれることはないのだ。(どれだけ変な名前なんだ...!?)

ちなみに、dumpbinが.PDBを参照する機能は、.DLLをビルドした場所からコピーしても有効になる。
DLLをデバッグ情報の生成を"はい"にしてビルドすると、.PDBファイルのフルパス名がDLLの中に埋め込まれているからだ。

しかし、.PDBの参照はファイル名だけではないようで、
  1. DLLをビルドする
  2. DLLを別のフォルダにコピーする → A.DLL とする
  3. dumpbin/exports A.DLLすると関数名が見える
  4. DLLをリビルドする(※ソースコードや設定変更など一切なし)
  5. dumpbin/exports A.DLLすると関数名はもはや見えない
という結果になった。

A.DLLをコピーして.PDBを削除すると、.PDBを再度作成しても参照してはくれないのだ。
おれおれ詐欺にはひっかからないってことらしい。

でも、A.DLLにはPDBファイルのフルパス名は埋め込まれているわけで、バイナリエディタかなにかを使えば、ビルドした時のフォルダ名が見えてしまうってことだ。

あ〜やっぱり恥ずかしいフォルダ名がばれちゃうってことじゃん。(どれだけ変な名前なんだ...!? 2回目)

.DEFでNONAMEしても関数名見えちゃうじゃん

え~知らなかった。
恥ずかしい関数名とかつけてなかったかなぁ・・・。
Windowsにもstripあるのかな?
※投稿直後に.DEFでNONAMEしたら関数名は見えないことがわかった
StudyDLL.cpp
int WINAPI Function_I_want_to_hide_its_name(int argc, char* argv)
{
return 0;
}
StudyDLL.def
StudyDLL.def

LIBRARY "StudyDLL"

EXPORTS
Function_I_want_to_hide_its_name @1 NONAME
dumpbin /exports StudyDLL.dll
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file StudyDLL.dll

File Type: DLL

Section contains the following exports for StudyDLL.dll

00000000 characteristics
49E4590C time date stamp Tue Apr 14 18:36:12 2009
0.00 version
1 ordinal base
1 number of functions
0 number of names

ordinal hint RVA name

1 00001000 [NONAME] ?Function_I_want_to_hide_its_name@@YGHHPAD@Z
(int __stdcall Function_I_want_to_hide_its_name(int,char *))

Summary

1000 .data
1000 .rdata
1000 .reloc
1000 .rsrc
1000 .text