设为首页 收藏本站
查看: 586|回复: 0

IIS服务程序在Win7,Window Server 2008下与应用程序模块(如DLL)之间的调用注意事项

[复制链接]

尚未签到

发表于 2015-5-17 08:29:39 | 显示全部楼层 |阅读模式
IIS服务程序在Win7,Window Server 2008下与应用程序模块(如DLL)之间的调用注意事项
    微软Window XP后的操作系统把服务程序(如IIS服务)和应用程序分隔在不同的session(服务程序运行在会话0层)中,所以应用程序与服务程序之前进行信息交互时与在XP上存在区别,遇到的情况主要有:
a)按同一会话层的方式发送消息,双方相互会收不到。
b)按同一会话层的方式进行参数传递,遇到寻址方式不一样的情况会寻址出错。
    针对以上a)和b)两的点解决方法:
a)的解决方法:修改双方的消息发送方式,如可以通过创建 命名管道(named pipes)或者是进程通信(如内存文件映射实现内存共享)来解决。
b)的解决方法:
1)双方使用相同的寻址方式,并由发起者创建好内存区域;
2)进程通信(如内存文件映射实现内存共享)来解决;
3)直接通过访问指定文件的方式来实现信息交互。

以下为使用相同的寻址方式,并由发起者创建好内存区域的示例:
1.首先使用VS2008创建一个WEB工程,并在主页面调用VSC++ DLL和delphi DLL如下所示(主页面代码):
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

using System.Reflection;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;

namespace WebApplication1 //把此处的命令空间名称改为自己工程的命令空间即可 创建网页工作在此不说//明
{
    public partial class _Default : System.Web.UI.Page
    {
        //delphi DLl
        private delegate int _intandstr(int intvalue, byte[] outstr, byte[] licenceinfo, byte[] len);
        private _intandstr intandstrFun;
        private delegate void _intandstrA(int intvalue, byte[] outstr, byte[] licenceinfo, byte[] len, byte[] ResultValue);
        private _intandstrA intandstrAFun;  
        private const string testdllFilePath = "\\bin\\testdll.dll";

        //VS C++     
        private delegate int _ParseLicenseDataA(byte[] aUnitName, int aUnitNameLen, byte[] aLicenseInfo, byte[] aLen);
        private _ParseLicenseDataA ParseLicenseDataAFun;
        private const string CalldllFilePath = "\\bin\\licenseWin.dll";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {

                //delphi DLL
                try
                {
                    int hModule = DLLWrapper.LoadLibrary(MapPath("") + testdllFilePath);
                    if (hModule == 0)
                    {
                        return;
                    }

                    intandstrFun = (_intandstr)DLLWrapper.GetAddress(hModule, "intandstr", typeof(_intandstr));
                    if (intandstrFun != null)
                    {                       
                        byte[] outstr = Encoding.Default.GetBytes("1111111111111111111111111111111111111111111111111111111111111111111111111111111111");
                        byte[] licenceinfo = new byte[1000];
                        byte[] len = new byte[2];


                        int resultStrValue1 = intandstrFun(100, outstr, licenceinfo, len);
                        string xmlReusl = outstr.ToString();
                        int valueconst = 50;
                        if ((outstr[1] == valueconst) && (outstr[10] == valueconst) && (outstr[0] == 49) && (outstr[11] == 49))
                        {
                            int InfoLen = (len[0]  0))
                            {
                                Response.Write("alert('" + "测试调用delphi dll intandstr方法修改传入的参数和返回参数值OK" + "');");
                            }
                            else
                            {
                                Response.Write("alert('" + "测试调用delphi dll intandstr方法修改返回值不对" + "');");
                            }
                        }
                    }
                    else
                    {
                        Response.Write("alert('" + "测试调用delphi dll 方法加载失败!。" + "');");
                    }                  
                 }
                catch
                {
                    Response.Write("alert('" + "测试调用 delphi dll 失败" + "');");
                    //Page.Response.Redirect("../Common/RepeatLoginTip.htm");
                }


                //VS C++ DLL
                try
                {
                    string UnitName = "abc";

                    int hModule = DLLWrapper.LoadLibrary(MapPath("") + CalldllFilePath);
                    if (hModule == 0)
                    {
                        Response.Write("alert('" + "测试调用 VC C++ DLL Dll文件加载失败" + "');");
                        return;
                    }

                    ParseLicenseDataAFun = (_ParseLicenseDataA)DLLWrapper.GetAddress(hModule, "ParseLicenseDataA", typeof(_ParseLicenseDataA));
                    UnitName = "111111111111111111111111111111111111111111111111";
                    byte[] byteUnitName = Encoding.Default.GetBytes(UnitName);
                    byte[] bytelicenceinfo = new byte[5000];
                    byte[] bytelen = new byte[2];
                    byte[] byteLicenseLen = Encoding.Default.GetBytes(StationName);


                    int ResultInt = ParseLicenseDataAFun(byteUnitName, 100, bytelicenceinfo, bytelen);
                    if ((ResultInt != 100) && (bytelen[0] == 0) && (bytelen[1] == 4))
                    {
                        if ((byteUnitName[0] == 50) && (byteUnitName[1] == 50) && (byteUnitName[2] == 50) && (byteUnitName[3] == 49))
                        {
                            if ((bytelicenceinfo[0] == 49) && (bytelicenceinfo[1] == 50) && (bytelicenceinfo[2] == 97) && (bytelicenceinfo[3] == 98))
                            {
                                Response.Write("alert('" + "测试调用 VS C++ DLL ParseLicenseDataA方法成功" + "');");
                            }
                        }
                    }
                    else
                    {
                        Response.Write("alert('" + "测试调用 VS C++ DLL ParseLicenseDataA方法失败" + "');");
                    }
                }
                catch
                {
                    Response.Write("alert('" + "测试调用 VS C++ DLL 接口失败" + "');");
                }
            }

        }
    }
}


public class DLLWrapper
{
    public DLLWrapper()
    {
    }

    ///
    /// API LoadLibrary
    ///
    [DllImport("Kernel32")]
    public static extern int GetProcAddress(int handle, String funcname);

    ///
    /// API GetProcAddress
    ///
    [DllImport("Kernel32")]
    public static extern int LoadLibrary(String funcname);

    [DllImport("Kernel32")]
    public static extern int FreeLibrary(int handle);

    //
    ///通过非托管函数名转换为对应的委托
    ///
    ///通过LoadLibrary获得的DLL句柄
    ///非托管函数名
    ///对应的委托类型
    ///委托实例,可强制转换为适当的委托类型
    public static Delegate GetAddress(int dllModule, string functionname, Type t)
    {
        int addr = GetProcAddress(dllModule, functionname);
        if (addr == 0)
            return null;
        else
            return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);

    }

    ///
    ///将表示函数地址的IntPtr实例转换成对应的委托, by jingzhongrong
    ///
    public static Delegate GetDelegateFromIntPtr(IntPtr address, Type t)
    {
        if (address == IntPtr.Zero)
            return null;
        else
            return Marshal.GetDelegateForFunctionPointer(address, t);
    }

    ///
    ///将表示函数地址的int转换成对应的委托,by jingzhongrong
    ///
    public static Delegate GetDelegateFromIntPtr(int address, Type t)
    {
        if (address == 0)
            return null;
        else
            return Marshal.GetDelegateForFunctionPointer(new IntPtr(address), t);
    }


}

2.使用VS 2008创建 VC++Win32  DLL工程如下所示:
VS C++ DLL接口声明头文件:
#ifndef TestDll_H_
#define TestDll_H_
#ifdef MYLIBDLL
#define MYLIBDLL extern "C" _declspec(dllimport)
#else
#define MYLIBDLL extern "C" _declspec(dllexport)
#endif
MYLIBDLL int Add(int plus1, int plus2);
MYLIBDLL int test(int value1);
MYLIBDLL int ParseLicenseDataA(char* aUnitName, int aUnitNameLen, char* aLicenseInfo, char * aLen);

#endif

VS C++ DLL 接口方法实现:

#include "stdafx.h"
#include "licenseWin.h"
#include
using namespace std;

int test(int value1)
{
   int ResultValue = value1 * value1;
   return ResultValue;
}

int Add(int plus1, int plus2)
{
int add_result = plus1 + plus2;
return add_result;
}

int ParseLicenseDataA(char* aUnitName, int aUnitNameLen, char* aLicenseInfo, char * aLen)
{
if (aUnitNameLen == 100)
{
aUnitName[0] = 50;//2
aUnitName[1] = 50;
aUnitName[2] = 50;
aLicenseInfo[0] = 49; //1
aLicenseInfo[1] = 50;
aLicenseInfo[2] = 97;//a
aLicenseInfo[3] = 98;
aLen[0] = 0;
aLen[1] = 4;
return 4;
}
else
{
return aUnitNameLen;

}
}

VS C++ 接口导出:
LIBRARY licenseWin
EXPORTS
; 此处可以是显式导出
Add
test
ParseLicenseDataA


3.使用delphi创建DLL工程如下所示:
Delphi DLL工程文件:
library testdll;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes,
  dllFunUnit in 'dllFunUnit.pas';

{$R *.res}

exports
  intandstr,
  intandstrA;

begin
End.

Delphi DLL接口代码实现:
unit dllFunUnit;

interface

function intandstr(intvalue: Integer; instr: PChar; licenceinfo: PChar; len: PChar): Integer; stdcall ;
function intandstrA(intvalue: Integer; instr: PChar; licenceinfo: PChar; len: PChar): PChar; stdcall ;

implementation

uses
  Dialogs, SysUtils;

function intandstr(intvalue: Integer; instr: PChar; licenceinfo: PChar; len: PChar): Integer; stdcall ;
const
  str = '2222222222';
var
  LicenceStr: PChar;
  licenceLen: Integer ;
  tempLen: array[0..1] of Byte;
begin
  Result := 0;
  if intvalue > 0 then
  begin
    //instr[1] := str[1];//修改无效,需要使用move进行内存复制
    Move(str[1], instr[1], Length(str)); //即使用move修改传入参数的内容
    LicenceStr := PChar('112233445566778899中国abc~');
    licenceLen := Length(LicenceStr);
    Move(LicenceStr[0], licenceinfo[0], licenceLen);  //使用move内存复制方式输出信息
    //len[0] := licenceLen shr 8; //直接修改无效,需要使用move进行内存复制
    tempLen[0] := licenceLen shr 8;
    Move(tempLen[0],len[0],1);
    tempLen[1] := licenceLen and $00FF;
    Move(tempLen[1],len[1],1);
    Result := licenceLen;
  end;
end;

function intandstrA(intvalue: Integer; instr: PChar; licenceinfo: PChar; len: PChar): PChar; stdcall ;
const
  str = '2222222222';
var
  LicenceStr: PChar;
  licenceLen: Integer ;
  tempLen: array[0..1] of Byte;
begin
  Result := 0;
  if intvalue > 0 then
  begin
    //instr[1] := str[1];//修改无效,需要使用move进行内存复制
    Move(str[1], instr[1], Length(str)); //即使用move修改传入参数的内容
    LicenceStr := PChar('112233445566778899中国abc~');
    licenceLen := Length(LicenceStr);
    Move(LicenceStr[0], licenceinfo[0], licenceLen);  //使用move内存复制方式输出信息
    //len[0] := licenceLen shr 8; //直接修改无效,需要使用move进行内存复制
    tempLen[0] := licenceLen shr 8;
    Move(tempLen[0],len[0],1);
    tempLen[1] := licenceLen and $00FF;
    Move(tempLen[1],len[1],1);
    Move(LicenceStr[0], Result[0], licenceLen);
    //ShowMessage(Result);//注意在WIN7下非开发环境下,即发布后,由于运行在不同的会话层,不能显示窗体,显示也看不到,看不到也就关闭不了窗体,
//关闭不了会引起网页程序请求超时,C/S程序直接当机
  end;
end;

End.

4.以上步骤做完后,把VS C++的DLL和dlephi 的DLL文件拷贝到 VS 2008的网页工程bin目录(也可以直接设置VS C++和delphi工程的编译输出目录为VS 2008的网页工程bin目录)。
5.在WIN7下IIS管理器发布此网页程序(先要安装IIS),通过浏览布置好的网站即可查看到调用VS C++的DLL和Delphi DLL的效果。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-67650-1-1.html 上篇帖子: win7下启动iis对json文件的支持 下篇帖子: mklink命令转移win7系统盘文件夹users和programdata(附xp的方法)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表