您当前的位置:首页 > 计算机 > 编程开发 > C语言

定制与开发应用之二:可扩展编程C语言API

时间:12-30来源:作者:点击数:

上次讲到了两种库文件MyLanguageInvokeSPSSXD和InvokeMyLanguage。本节重点解析一下MyLanguageInvokeSPSSXD。

SPSS的C语言应用编程接口(SPSSXD API)在动态链接库spssxd.dll中包含两个方面的底层功能:第一种是提交操作请求给SPSS,请求的典型返回结果为错误码,通过错误码,可以得出操作结果是成功还是出现其他异常和错误。

第二种是提交信息请求给SPSS,请求的典型返回结果是所请求的信息。这些底层功能实现对SPSS的功能操作,变量字典的获取,输出结果XML工作区信息的读取,对SPSS活动数据集的操作。SPSS的C语言应用编程接口帮助文档可以在SPSS提供的可扩展性编程spssxdAPI文件夹下找到。

外部语言程序直接调用SPSS C语言应用编程接口的基本工作过程可以描述为以下步骤:

  1. 外部语言准备调用SPSS。
  2. 检查SPSS后台程序是否运行,没有运行则装载MyLanguageInvokeSPSSXD,如果运行则进入下一步。
  3. 获得SPSS后台程序句柄。成功则继续,否则中断。
  4. 初始化相关功能指针。成功则完整SPSS调用准备,否则中断。
  5. 启动SPSS通讯。成功则进入下一步,否则中断。
  6. 检查SPSS后台状态正常时,操作SPSS功能,输出分析结果。
  7. 调用任务完成,终止SPSS通讯。
  8. 卸载动态链接库。
  9. 外部语言程序调用SPSS结束。

以下为SPSS提供的官方样例程序。C语言程序的主入口:

int _tmain(int argc, _TCHAR* argv[])
{
//初始化传入参数个数为1
int count = 1;
   if (argc >1)
       count = atoi(argv[1]);

__time64_t stime; //time.h time类中定义的结构
   _time64( &stime );//the start time of the test

//装载DLL
int load = LoadLib();
//判断是否成功
    if ( load != 0 ){
       std::cout << "load failure, exitcode = " << load << std::endl;
       return -1;
   }

//创建暂存结果的文件
std::string tempfile = "d:/temp/result.txt";
   std::string tempresult("-out ");
   tempresult = tempresult + tempfile;
  
//申明状态检查
int err = 0;
//启动SPSS通信
err = StartSpss(tempresult.c_str());
if( err != 0 ){
          std::cout << "start spss failed, exitcode = " << err << std::endl;
       return -1;
          }
//To Do Work
for (int i=0; i<count; i++){
          //判断是否就绪
          int ready = IsBackendReady();
          if( ready != 1 ){
                   std::cout << "backend is not ready, exitcode = " << ready << std::endl;
                   return -1;
          }
          //确定要处理的文件
          std::vector<std::string> fList; //data file list
          filelist(fList);
          //检验并打开文件
          int index=i%(int)fList.size();
       err = getfile(fList[index].c_str());
       if (err !=0 ){
           std::cout << "get file error: filename=>" << fList[index] << " err=" << err << std::endl;
                   return -1;
                   }
          //测试XPath和通用功能
           XPathAndGeneralFunctions(fList[index].c_str());
           int iPosition = 0;
           Displayresult(tempfile.c_str(), iPosition);
          std::cout <<"The end of XPATH result output! \n"<<endl;
          //开始一个用户的过程
          StartProcedure("UserProc1");
          //操作数据库
          DataSourceFunctions();
          Displayresult(tempfile.c_str(), iPosition);
          //测试转轴表
          PivotTableFunctions();
          Displayresult(tempfile.c_str(), iPosition);
          //结束过程
          EndProcedure();
          //测试数据数据集
          DataStepFunctions();
          Displayresult(tempfile.c_str(), iPosition);
          }
//终止SPSS通信
StopSpss();
//卸载DLL
FreeLib();
return 0;
}
进一步深入LoadLib(),该方法由load.cpp提供,源代码如下:
/**
* load.c -
* load and unload spssxd.dll dynamically.
* COPYRIGHT
* Copyright 2005 by SPSS Inc. All rights reserved.
*/

#include "load.h"
#include <iostream>
using namespace std;
//declare the function pointer.
FP_IsBackendReady                   IsBackendReady =              NULL;
FP_IsXDriven                        IsXDriven =                   NULL;
FP_StartSpss                        StartSpss =                   NULL;
FP_StopSpss                         StopSpss =                    NULL;
FP_Submit                           Submit =                      NULL;
FP_QueueCommandPart                 QueueCommandPart =            NULL;
FP_PostSpssOutput                   PostSpssOutput =              NULL;
FP_GetVariableCount                 GetVariableCount =            NULL;
FP_GetRowCount                      GetRowCount =                 NULL;
FP_GetVariableName                  GetVariableName =             NULL;
FP_GetVariableLabel                 GetVariableLabel =            NULL;
FP_GetVariableType                  GetVariableType =             NULL;
FP_GetVariableFormat                GetVariableFormat =           NULL;
FP_GetVariableMeasurementLevel      GetVariableMeasurementLevel = NULL;
FP_CreateXPathDictionary            CreateXPathDictionary =       NULL;
FP_RemoveXPathHandle                RemoveXPathHandle =           NULL;
FP_EvaluateXPath                    EvaluateXPath =               NULL;
FP_GetStringListLength              GetStringListLength =         NULL;
FP_GetStringFromList                GetStringFromList =           NULL;
FP_RemoveStringList                 RemoveStringList =            NULL;
FP_GetXmlUtf16                      GetXmlUtf16 =                 NULL;
FP_GetHandleList                    GetHandleList =               NULL;
FP_GetNumericValue                  GetNumericValue =             NULL;
FP_GetStringValue                   GetStringValue =              NULL;
FP_MakeCaseCursor              MakeCaseCursor =             NULL;
FP_NextCase                         NextCase =                    NULL;
FP_RemoveCaseCursor                 RemoveCaseCursor =            NULL;
FP_GetVariableFormatType            GetVariableFormatType =       NULL;
FP_GetCursorPosition                GetCursorPosition =           NULL;

FP_StartPivotTable                StartPivotTable = NULL;                                                
FP_AddDimension                   AddDimension = NULL;                                                
FP_AddStringCategory              AddStringCategory = NULL;                                                
FP_SetFormatSpecCount             SetFormatSpecCount = NULL;                                                
FP_SetNumberCell                  SetNumberCell = NULL;                                                
FP_AddCellFootnotes               AddCellFootnotes = NULL;                                                
FP_AddTextBlock                   AddTextBlock = NULL;
FP_StartProcedure                 StartProcedure = NULL;                                              
FP_EndProcedure                   EndProcedure = NULL;

FP_StartDataStep                StartDataStep = NULL;                                                
FP_CreateDataset                  CreateDataset = NULL;                                            
FP_GetCaseCountInDS             GetCaseCountInDS = NULL;
FP_InsertCase            InsertCase = NULL;
FP_DeleteCase                 DeleteCase = NULL;                         
FP_GetVarTypeInDS               GetVarTypeInDS = NULL;
FP_GetNCellValue                   GetNCellValue = NULL;
FP_GetCCellValue                GetCCellValue = NULL;
FP_SetNCellValue                   SetNCellValue = NULL;
FP_SetCCellValue                   SetCCellValue = NULL;
FP_EndDataStep                EndDataStep = NULL;

HMODULE pLib = NULL; //初始化一个句柄
const char libName[] = "spssxd_p.dll"; //SPSS的动态链接库
const int LOAD_FAIL = 1011;
const int LOAD_SUCCESS = 0;

//Initialize the function pointer
void InitializeFP()
{
   //GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址,参数为句柄加函数名,返回的是动态链接库的空间地址
IsBackendReady = (FP_IsBackendReady)GetProcAddress(pLib,"IsBackendReady");
   //上句检查动态链接库后台已经准备就绪,设置后台准备状态为就绪布尔型
//下句设置动态链接库驱动正确布尔型
IsXDriven = (FP_IsXDriven)GetProcAddress(pLib,"IsXDriven");
//设置动态链接库为SPSS开始的命令行字符串
   StartSpss = (FP_StartSpss)GetProcAddress(pLib,"StartSpss");
//设置动态链接库为SPSS结束整型
   StopSpss = (FP_StopSpss)GetProcAddress(pLib,"StopSpss");
//设置动态链接库为SPSS提交的命令行包括提交命令及其长度返回整型
   Submit = (FP_Submit)GetProcAddress(pLib,"Submit");
//设置动态链接库为SPSS提交的队列命令包括提交行命令及其长度返回整型
   QueueCommandPart = (FP_QueueCommandPart)GetProcAddress(pLib,"QueueCommandPart");
//设置动态链接库为SPSS返回结构的文本返回整型
   PostSpssOutput = (FP_PostSpssOutput)GetProcAddress(pLib,"PostSpssOutput");
//设置动态链接库为SPSSF能取得的变量个数返回整型
   GetVariableCount = (FP_GetVariableCount)GetProcAddress(pLib,"GetVariableCount");
//设置动态链接库为SPSSF能取得的记录行数返回整型
   GetRowCount = (FP_GetRowCount)GetProcAddress(pLib,"GetRowCount");
//设置动态链接库为SPSS能取得的变量名称返回字符型
   GetVariableName = (FP_GetVariableName)GetProcAddress(pLib,"GetVariableName");
//设置动态链接库为SPSS能取得的变量标签返回字符型
   GetVariableLabel = (FP_GetVariableLabel)GetProcAddress(pLib,"GetVariableLabel");
//设置动态链接库为SPSS能取得的变量类型返回字符型
   GetVariableType = (FP_GetVariableType)GetProcAddress(pLib,"GetVariableType");
//设置动态链接库为SPSS能取得的变量格式返回字符型
   GetVariableFormat = (FP_GetVariableFormat)GetProcAddress(pLib,"GetVariableFormat");
//设置动态链接库为SPSS能取得的变量评价层次返回整型
   GetVariableMeasurementLevel = (FP_GetVariableMeasurementLevel)GetProcAddress(pLib,"GetVariableMeasurementLevel");
   //设置动态链接库为SPSS创建的XPATH字典返回整型
CreateXPathDictionary = (FP_CreateXPathDictionary)GetProcAddress(pLib,"CreateXPathDictionary");
   //设置动态链接库为SPSS删除的XPATH处理返回整型
RemoveXPathHandle = (FP_RemoveXPathHandle)GetProcAddress(pLib,"RemoveXPathHandle");
   //设置动态链接库为SPSS评估的XPATH处理(包括处理,上下文,表达式)无返回
EvaluateXPath =(FP_EvaluateXPath)GetProcAddress(pLib,"EvaluateXPath");
   //设置动态链接库为SPSS处理的列表返回整型
GetStringListLength = (FP_GetStringListLength)GetProcAddress(pLib,"GetStringListLength");
   //设置动态链接库为SPSS处理的字符列表返回字符
GetStringFromList = (FP_GetStringFromList)GetProcAddress(pLib,"GetStringFromList");
   //设置动态链接库为SPSS删除处理的字符列表返回字符
RemoveStringList = (FP_RemoveStringList)GetProcAddress(pLib,"RemoveStringList");
   //设置动态链接库为SPSS处理的XML返回字符
GetXmlUtf16 = (FP_GetXmlUtf16)GetProcAddress(pLib,"GetXmlUtf16");
   //设置动态链接库为SPSS处理的列表无返回
GetHandleList = (FP_GetHandleList)GetProcAddress(pLib,"GetHandleList");
   //设置动态链接库为SPSS结果和变量索引返回整型
GetNumericValue = (FP_GetNumericValue)GetProcAddress(pLib,"GetNumericValue");
   //设置动态链接库为SPSS结果、缓冲长度和变量索引返回整型
GetStringValue = (FP_GetStringValue)GetProcAddress(pLib,"GetStringValue");
//创建游标 返回整型
MakeCaseCursor = (FP_MakeCaseCursor)GetProcAddress(pLib,"MakeCaseCursor");
//移动到下一个案例 返回整型
NextCase = (FP_NextCase)GetProcAddress(pLib,"NextCase");
//移除案例游标返回整型
RemoveCaseCursor = (FP_RemoveCaseCursor)GetProcAddress(pLib,"RemoveCaseCursor");
//由格式类型拿到变量格式类型返回整型
GetVariableFormatType = (FP_GetVariableFormatType)GetProcAddress(pLib,"GetVariableFormatType");
   //得到游标位置
GetCursorPosition = (FP_GetCursorPosition)GetProcAddress(pLib,"GetCursorPosition");
//
   StartPivotTable = (FP_StartPivotTable)GetProcAddress(pLib,"StartPivotTable");
   AddDimension = (FP_AddDimension)GetProcAddress(pLib,"AddDimension");
   AddStringCategory = (FP_AddStringCategory)GetProcAddress(pLib,"AddStringCategory");
   SetFormatSpecCount = (FP_SetFormatSpecCount)GetProcAddress(pLib,"SetFormatSpecCount");
   SetNumberCell = (FP_SetNumberCell)GetProcAddress(pLib,"SetNumberCell");
   AddCellFootnotes = (FP_AddCellFootnotes)GetProcAddress(pLib,"AddCellFootnotes");
   AddTextBlock = (FP_AddTextBlock)GetProcAddress(pLib,"AddTextBlock");
StartProcedure = (FP_StartProcedure)GetProcAddress(pLib,"StartProcedure");
   EndProcedure = (FP_EndProcedure)GetProcAddress(pLib,"EndProcedure");

StartDataStep =        (FP_StartDataStep)GetProcAddress(pLib,"StartDataStep");
CreateDataset =      (FP_CreateDataset)GetProcAddress(pLib,"CreateDataset");
GetCaseCountInDS = (FP_GetCaseCountInDS)GetProcAddress(pLib,"GetCaseCountInDS");
InsertCase = (FP_InsertCase)GetProcAddress(pLib,"InsertCase");
DeleteCase = (FP_DeleteCase)GetProcAddress(pLib,"DeleteCase");
GetVarTypeInDS = (FP_GetVarTypeInDS)GetProcAddress(pLib,"GetVarTypeInDS");
GetNCellValue =      (FP_GetNCellValue)GetProcAddress(pLib,"GetNCellValue");
GetCCellValue =      (FP_GetCCellValue)GetProcAddress(pLib,"GetCCellValue");
SetNCellValue =       (FP_SetNCellValue)GetProcAddress(pLib,"SetNCellValue");
SetCCellValue =       (FP_SetCCellValue)GetProcAddress(pLib,"SetCCellValue");
EndDataStep = (FP_EndDataStep)GetProcAddress(pLib,"EndDataStep");

}

int LoadLib()
{
//判断是否得到句柄pLib
   if(NULL == pLib){ //libName = "spssxd.dll"
       //find out spssxd.dll module, it will success when spss drive
       pLib = GetModuleHandle(libName);//如果SPSS是运行的,这里获得名为spssxd.dll的句柄
       //find out spssxd.dll module failure, load it.
       if(NULL == pLib) {//SPSS程序此时没有运行,所以这里句柄为Null
           pLib = LoadLibrary(libName);//重新载入名为spssxd.dll的链接库道地址空间,进而访问该资源
       }
       //load spssxd.dll module success, initialize the function pointer这里成功载入动态链接库
       if (pLib) {//载入动态链接库spssxd.dll,并开始初始化功能指针
           InitializeFP();
       }
       //load failure
       else {
           return LOAD_FAIL;//装载失败
       }
   } 
   return LOAD_SUCCESS;//装载成功
}

void FreeLib()
{
   FreeLibrary(pLib);
   pLib= NULL;

   IsBackendReady = NULL;
   IsXDriven = NULL;
   StartSpss = NULL;
   StopSpss = NULL;
   Submit = NULL;
   QueueCommandPart = NULL;
   PostSpssOutput = NULL;
   GetVariableCount = NULL;
   GetRowCount = NULL;
   GetVariableName = NULL;
   GetVariableLabel = NULL;
   GetVariableType = NULL;
   GetVariableFormat = NULL;
   GetVariableMeasurementLevel = NULL;
   CreateXPathDictionary = NULL;
   RemoveXPathHandle = NULL;
   EvaluateXPath = NULL;
   GetStringListLength = NULL;
   GetStringFromList = NULL;
   RemoveStringList = NULL;
   GetXmlUtf16 = NULL;
   GetHandleList = NULL;
   GetNumericValue = NULL;
   GetStringValue = NULL;
    MakeCaseCursor = NULL;
   NextCase = NULL;
   RemoveCaseCursor = NULL;
   GetVariableFormatType = NULL;
   GetCursorPosition = NULL;
    StartPivotTable = NULL;                                                
    AddDimension = NULL;                                                
    AddStringCategory = NULL;                                                
    SetFormatSpecCount = NULL;                                                
    SetNumberCell = NULL;                                                
    AddCellFootnotes = NULL;                                                
    AddTextBlock = NULL;
    StartProcedure = NULL;                                              
    EndProcedure = NULL;
    StartDataStep = NULL;                                                
    CreateDataset = NULL;                                            
    GetCaseCountInDS = NULL;
    InsertCase = NULL;
    DeleteCase = NULL;                         
    GetVarTypeInDS = NULL;
    GetNCellValue = NULL;
    GetCCellValue = NULL;
    SetNCellValue = NULL;
    SetCCellValue = NULL;
    EndDataStep = NULL;
}

 

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门