devlog

http://twitter.com/yusukei

いまさらだけどMaya 2013のお話

いまさらですが、Maya 2013を使おうとしたときにハマった小ネタです。

Maya 2012でnumpyなどを使っていたのですが、Maya 2013で使おうとしたら読み込めない!

相変わらず不親切なメッセージが。
ImportError: DLL load failed: 指定されたモジュールが見つかりません。
と出るだけ。

まぁ、この時点で、msvcr90.dllであろうことは容易に予想はつくのですが。
ちょとっと検索してみると、

なんて記事が出てきます。
ここに書いてあるように、根本的にはリビルドするのが正攻法です。

とはいえ、msvcr90.dllとmsvcr100.dllが混在しても動くもの、動かないものがあるのは
納得がいかないので、なぜ動かないのか調べてみました。というのが今回のお話。

さて、ロードできないのがmsvcr90.dllであることから原因としてはmanifest周りしか考えられません。
というわけで、どんなmanifestが埋め込んであるか調べてみました。

manifestを取り出すにはVisualStudioに付属のコマンドを使うのが簡単です。
DLLのmanifestはID:2であるので以下のようなコマンドで取り出せます。

mt -inputresource:QtCore.pyd;2 -out:QtCore.pyd.manifest

これはPySideのQtCore.pydのmanifestを取り出した例です。
ちなみに、この2012用にビルドしたPySide.QtCoreはmaya 2013でも読み込むことができています。(自前ビルドですが)
これをテキストエディタで開くと

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="amd64" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

こんな感じのXMLになっています。
このXMLにどのバージョンのmsvcr90を読み込めばいいのかという情報が書かてれいます。

で、お次にnumpyのmultiarray.pydを取り出してみると、

mt.exe : general error c101008c: Failed to read the manifest from the resource of file "multiarray.pyd". 

と言われてしまいます。要は埋め込みmanifestが存在しないということです。

ということで、numpyのpydにはmanifestが存在しないためロードできないという感じです。
実際、先ほど取り出したmanifestをmultiarray.pydに埋め込んでみます。

mt -manifest QtCore.pyd.manifest -outputresource:multiarray.dll;2

再度、Maya 2013でimportすると読み込めないpydの名前が変わっているかと思います。
numpyのすべてのpydに対してこれを行えば読み込めるようになるかと思います。(未確認)