ホーム   フォーラム   FAQ
 
メインメニュー
ログイン
ユーザー名:

パスワード:


パスワード紛失

VC++(CLR)で作成したDLLがMagicから認識されない

  • このフォーラムに新しいトピックを立てることはできません
  • このフォーラムではゲスト投稿が禁止されています
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 .2 .3 .4 | 投稿日時 2016-5-19 16:17
Quantum  新米   投稿数: 3
いつもお世話になっております。

C++/CLRで作成したDLLをuniPaaS V1からCallDLLまたはコールUDPでコールしようとしております。

当初、開発版では問題なく呼べていたのですが、実行環境で実行すると「ユーザモジュールが見つかりません」と出てしまいます。

解決策をご教示いただければと思います。

詳細は以下の通りです。
・市販のSpreadsheetGearを利用するためのDLLを作成する。SpreadsheetGearはマネージコードでのみ動作するのでCLRでDLLを作成した。
・uniPaaS V1のバッチタスクから当初CallDLLでコールしていた。
・C++ではクラスメソッドではなく関数として実装している。
・自分の開発環境の開発版から実行するとuniPaaSからDLLを呼べている。
・自分の開発環境の実行版(Client V1\uniRTE.exe)から実行してもuniPaaSからDLLを呼べている。
・他のマシンの開発版から実行するとuniPaaSからDLLを呼べている。
・開発版をインストールしていないマシンの実行版から実行すると「ユーザモジュールが見つかりません」と出る。
・なお、SpreadsheetGearを使用しない関数でも同じメッセージが出る。

以下、参考のためソースを載せます。整数値を返す関数になります。(なのでSpreadsheetGearは使っていません)

<Test.h>
#pragma once

using namespace System;

namespace Test {

public ref class Class1
{
// TODO: このクラスの、ユーザーのメソッドをここに追加してください。
};
}


<Test.cpp>
// これは メイン DLL ファイルです。

#include "stdafx.h"
#include <windows.h>
#include "Test.h"
#include "userdll.h"


// Magicからコールしたい関数
long retnum()
{
return 111;
}


#define FUNC_CNT 1
/*-------------------------------------------------------------------------*/

static FUNC_DSC fdsc_tbl[FUNC_CNT] =
{
{ (Uchar *) "retnum", (void far *)retnum, 0, (Uchar *) "L" }
};

static EXT_MODULE ext_module =
{ 0, NULL_PTR, NULL_PTR, FUNC_CNT, fdsc_tbl, (Uchar *) "Test" };

void *MAGIC_BIND(void)
{
return (&ext_module);
}


<Test.def>
LIBRARY Test
EXPORTS
MAGIC_BIND
retnum


<userdll.h>
uniPaaSのインストールフォルダにあるものそのまま


以下試してみたことを記します。
・開発時はuserdll.hやMAGIC_BIND等を含めていなかったが、開発版では動いていた。
・CallDLLをCallDLLSやCallDLLFに置き換えても実行環境ではダメ。
・CallDLLをコールUDPに変えても、実行環境ではダメ。
・Visual Studioから生成されたDLL以外のファイルも、実行環境のV1 Plusフォルダの下に置いたがダメ。


過去スレも見ましたが、uniPaaS V1Plusのバッチタスクからは.NETのDLLは呼べないとあるのを見ましたが、それだと何故開発環境では動くのだろうかという疑問がわきます。

COMオブジェクトとして作れば可というのも見ましたが、それも実際やってみても動かずにおります。こちらはもう少しがんばってみます。

以上、長文となりましたが、何卒よろしくお願いいたします。
投票数:0 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2016-5-19 16:25
ISHIJIMA  長老 居住地: 静岡県  投稿数: 1827
MAGICの問題ではないような気がします。
その実行環境に開発版を入れたら動きますか?
それで動かなければMAGICの問題ではないような気がします。
あとその実行環境でMAGIC以外からDLLを使用した場合動きますか
投票数:0 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2016-5-22 18:47
null  長老   投稿数: 191
マネージドの DLL は呼べないと思っている人ですが書いてある内容では呼べているのですね。
(参考に乗せている Test はアンマネージドのようにも見えるが、SpreadsheetGear を利用する DLL は
マネージドだと思うので、「udf からでも呼べるのかー」という認識で書いています)


実行時に「ユーザー関数が〜」ではなく、「ユーザモジュールが見つかりません」なので、dll が uniPaaS の
ランタイムから見えていないのだと思います。一時的に環境変数 PATH に DLL のパスを追加してみては?

ちなみに作成した dll が 64bit だと 32bit からは見えませんが内容を見る限りは 32bit の dll ですよね?

それでもユーザーモジュールが見つからないのであれば、
作成した dll 内から使用する dll が対象のマシンに入っていない可能性があります。
Visual Studio Tools の中にあるコマンドプロンプトから dumpbin で確認してみては?

dumpbin Test.dll /imports
で Test.dll が使用している dll を確認。
その dll があるか?パスが通っているか?など確認。

念のため、MAGIC_BIND retnum が正しくエクスポートされているか確認
dumpbin Test.dll /exports


実行版しか入っていない環境で動かないとのことなので
何となくこの手の dll が対象のマシンにないのが原因のような気がします。
http://devnet.magicsoftware.co.jp/download/tools_library/uipaasv1/msvcr71dll/
投票数:0 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 | 投稿日時 2016-5-23 14:47
Quantum  新米   投稿数: 3
ご返信いただきありがとうございます。

自己解決いたしました。

結論から言うとVisual C++のRuntimeがインストールされていないからでした。

他のいくつかのマシンで実行環境を作ってみたら、うまく動くのもありましたが、とあるマシンにおいて「MSVCR120.dllがありません」旨のメッセージが出て、そこからRuntimeがないのが原因ではないかということになりました。それで最初の問題のマシンにRuntimeをインストールしたら、うまく動くようになりました。

ちなみに、最初の問題のマシンでなぜ「MSVCR120.dllがありません」旨のメッセージが出ないのかは謎のままですが。

たいへんお騒がせしました。

それから、userdll.hやMAGIC_BINDがなくても動くようです。以下にソースを記しておきます。

<Test.h>
#pragma once

using namespace System;

namespace Test {

public ref class Class1
{
// TODO: このクラスの、ユーザーのメソッドをここに追加してください。
};
}


<Test.cpp>
#include "stdafx.h"
#include "Test.h"

// Magicからコールしたい関数
int retnum()
{
return 999;
}


<Test.def>
LIBRARY Test
EXPORTS
retnum


これをビルドしたDLLをCallDLLでコールできました。

以上、ありがとうございます。
投票数:0 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2016-5-23 17:46
null  長老   投稿数: 191
解決したようで。やはり、C や C++ のランタイムでしたか。

補足:
> それから、userdll.hやMAGIC_BINDがなくても動くようです。以下にソースを記しておきます。
はい。CallDLL() で呼ぶのであれば MAGIC_BIND は不要です。

外部コールの UDF や UDF() で呼ぶ場合は uniPaaS 内部での関数名と実際の関数を紐付ける為に、
MAGIC_BIND や { (Uchar *) "retnum", (void far *)retnum, 0, (Uchar *) "L" }
などの定義が必要になります。

ちなみに CallDLL の場合は呼び出し規約(cdecl stdcall ) とかに注意する必要があります。
投票数:0 平均点:0.00
前の投稿 - 次の投稿 | 親投稿 - 子投稿なし | 投稿日時 2016-5-25 10:44
Quantum  新米   投稿数: 3
>CallDLL() で呼ぶのであれば MAGIC_BIND は不要です。

そういうことでしたか。
UPFやUDFでコールするときのためのコードなんですね。

ありがとうございました。
投票数:0 平均点:0.00

  条件検索へ


Copyright (C) Magic Software Japan K.K. All Rights Reserved.
個人情報保護方針 会員規約