2025年4月2日 星期三 乙巳(蛇)年 正月初三 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > C语言

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

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

上次讲到了两种库文件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;
  • }

 

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