From: Daniel Berger Date: 2005-10-26T07:42:03+09:00 Subject: Re: mkmf, linking against a specific DLL on windows nobuyoshi nakada wrote: > Hi, > > At Tue, 18 Oct 2005 02:16:42 +0900, > Daniel Berger wrote in [ruby-talk:160905]: > > How do I link against a specific DLL on Windows again? I tried have_library, > > but that always looks for the .lib file apparently. > > What do you want to link against? AFAIK, VC link.exe can't > handle DLL files as input, without import library files (i.e., > lib files). > > -- > Nobu Nakada Ok, but you can generate a .lib file from a .def, and you can generate a .def from a .dll. Here's a script I cobbled together that did the trick: # libmaker.rb require "Win32API" GetShortPathName = Win32API.new("kernel32","GetShortPathName","PPL","L") MAX_PATH = 260 # Create a .def file from the results of a 'link -dump -exports' def create_def(dll_file, def_file = nil) raise "not a dll" unless File.extname(dll_file).downcase == ".dll" if def_file.nil? def_file = dll_file[0..-5] + ".def" end funcs = [] # Dunno if I've caught all the junk here. Seems to work. `link -dump -exports "#{dll_file}"`.each{ |line| func = line.split.last next if func.nil? next if func.empty? next if func.split("").first !~ /[A-Z]/ next if func == "Summary" next if func.upcase == "DLL" next if File.basename(func) == File.basename(dll_file) funcs.push(func) } File.open(def_file, "w+"){ |fh| fh.puts "NAME " + File.basename(dll_file) fh.puts "EXPORTS" funcs.each{ |func| fh.puts "\t#{func}" } } return def_file end # Create a .lib file from a .def file. Note that the lib command doesn't # seem to like long path names, so we'll shorten them. def create_lib(def_file, lib_file = nil) raise "not a .def" unless File.extname(def_file).downcase == ".def" if lib_file.nil? lib_file = def_file[0..-5] + ".lib" end buf = 0.chr * MAX_PATH buf[0..def_file.length-1] = def_file GetShortPathName.call(def_file, buf, buf.length) def_file = buf.split(0.chr).first lib_file = File.dirname(def_file) + "\\" + File.basename(lib_file) # This may generate a warning which you can ignore system("lib /DEF:#{def_file} /OUT:#{lib_file}") end dll_file = "C:\\foo\\bar\\baz.dll" def_file = "C:\\foo\\bar\\baz.def" def_file = create_def(dll_file) create_lib(def_file)