在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例Windows系统编程 → OPC PLC通讯 示例源码

OPC PLC通讯 示例源码

Windows系统编程

下载此实例
  • 开发语言:C/C++
  • 实例大小:0.03M
  • 下载次数:95
  • 浏览次数:1022
  • 发布时间:2018-03-16
  • 实例类别:Windows系统编程
  • 发 布 人:1950550905
  • 文件格式:.rar
  • 所需积分:2
 相关标签: c++ opc PLC

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

//
// RsiOpcConnect.cpp
// Example demonstrating the use of an OPC client to perform asynchronous
// functions to a device using "Connection Points".
//
// The asynchronous functionality in this sample program is based on the
// "OPC Data Access Custom Interface Standard", v2.0.
//
// Refer to Microsoft documentation for information on "Connection Points".
//
//		Revision history
//			Program created (EPD 02/11/00)
//
//

// Standard OPC header files
#include "opccomn.h"
#include "opccomn_i.c"
#include "opcda.h"
#include "opcda_i.c"

// Comdef.h required for Connection Point definitions
#include <comdef.h>	

#include "Sink.h"
#include "utils.h"

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>


//Function prototypes
OPCITEMRESULT *CreateItems(IOPCItemMgt* pOPCItemMgt, OPCITEMDEF *ItemArray, DWORD *dwCount);
IUnknown *CreateLocalServer(WCHAR *pwszServerName);
IUnknown *CreateRemoteServer(WCHAR *pwszServerName, WCHAR *pwszComputerName);
void GetWriteData(DWORD dwCount, VARIANT *pItemValues);

IOPCServer		*pOPCServer = NULL;


main()
{

	HRESULT			r1;
	IUnknown		*pUnkSvr = NULL;
	char			c;
	IOPCItemMgt		*pOPCItemMgt=NULL;
	OPCITEMDEF		*pItemArray=NULL;
	OPCITEMRESULT	*pAddResults=NULL;
	HRESULT			*pErrors=NULL;
	DWORD			n, dwCount;

	wchar_t			szwServerName[80]={L'\0'},
//					szwAccessPath[80]={L'\0'},
					szwItemName[80]={L'\0'},
					szwComputerName[80]={L'\0'};

	SetConsoleTitle("OPC Async Client Test (Connection Points)");

	// User enters OPC server name
	// For RSLinx, the server names are
	//   1.'rslinx opc server' (local)
	//   2.'rslinx remote opc server' (remote)
	printf("Enter the OPC server name\n>");
	_getws(szwServerName);
	

	// Initialize COM. To use this function, define _WIN32_DCOM in 'Settings'
	r1 = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
	if (FAILED(r1)){
		DisplaySystemError("Error at CoInitializeEx", r1);
		exit (1);
	}

	// User enters the type of OPC server
	printf("Enter the server type to create: L-local, R-Remote\n>");

	c = getch();
	char x = toupper(c);

	switch(x){

	case 'L':
		// Create a local RSLinx server object and obtain the IUnknown pointer
		pUnkSvr = CreateLocalServer(szwServerName);
		if (pUnkSvr == NULL){
			printf ("Error creating IUnknown pointer\n");
			CoUninitialize();
			exit(1);
		}
		break;


	case 'R':
		//User enters the computer node name
		printf("Enter the computer name:\n");
		_getws(szwComputerName);
		// Create a remote RSLinx server object and obtain the IUnknown pointer
		pUnkSvr = CreateRemoteServer(szwServerName, szwComputerName);
		if (pUnkSvr == NULL){
			printf ("Error creating IUnknown pointer\n");
			CoUninitialize();
			exit(1);
		}
		break;

	default:
		printf ("Unknown server type\nProgram ends\n");
		CoUninitialize();
		exit(1);
	}

	// Obtain a pointer to the OPC Server interface
	r1 = pUnkSvr->QueryInterface(IID_IOPCServer, (void**)&pOPCServer);
	if (FAILED(r1)){
		DisplaySystemError("Error attempting to get OPC Server pointer", r1);
		CoUninitialize();
		exit (1);
	}


	// Parameters required to add a group
	DWORD dwRequestedUpdateRate;	// Update rate requested by user
	DWORD dwRevisedUpdateRate;		// Update rate provided by server
	OPCHANDLE hClientGroup;			// Group handle assigned by user
	OPCHANDLE hServerGroup;			// Group handle returned by server
	LONG	lTimeBias = 240L;		
	BOOL	GroupActiveState = TRUE; // active state of the group
	wchar_t	szwGroupName[80];

	wcscpy(szwGroupName, L"_Group1"); // assigned the group a name

	hClientGroup = 0x100;
	dwRequestedUpdateRate = 1000;


	printf("\n...Attempting to add group\n");

	// Add a group to the server. A pointer to a group interface is returned.
	// In this case, it is the Item Management interface.
	r1 = pOPCServer->AddGroup(szwGroupName, GroupActiveState, dwRequestedUpdateRate, 
						   hClientGroup, &lTimeBias, NULL, 0,
						   &hServerGroup, &dwRevisedUpdateRate,
						   IID_IOPCItemMgt, (LPUNKNOWN*)&pOPCItemMgt);
	if (FAILED(r1)){
		DisplayError("Error attempting to add group", r1);
		pOPCServer->Release();
		exit (1);
	}
	else printf("Group %ls added successfully\n", szwGroupName);

	// Item count is set to 3. User will create three items.
	dwCount = 3;
	pItemArray = (OPCITEMDEF*)CoTaskMemAlloc(dwCount*sizeof(OPCITEMDEF));

	// Call function that allows user to add items to the group
	pAddResults = CreateItems(pOPCItemMgt, pItemArray, &dwCount);
	if (pAddResults == NULL){
		printf ("Could not add items to the group %ls\n", szwGroupName);
		pOPCItemMgt->Release();
		pOPCServer->Release();
		pUnkSvr->Release();
		exit(1);
	}

	IConnectionPointContainer *pCPC=NULL;

	// Get pointer the Connection Point Container
	r1 = pOPCItemMgt->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
	if (FAILED(r1)){
		DisplayError("Error attempting get Connection Point Container", r1);
		pOPCServer->Release();
		CoUninitialize();
		exit (1);
	}

	// Get pointer to the Data Callback connection point
	IConnectionPoint	*pConnPt=NULL;
	r1 = pCPC->FindConnectionPoint(IID_IOPCDataCallback, (IConnectionPoint**)&pConnPt);
	if (FAILED(r1)){
		DisplaySystemError("Error attempting to get Connection Point", r1);
		pOPCServer->Release();
		CoUninitialize();
		exit (1);
	}

	// Don't need this interface anymore. Get rid of it.
	pCPC->Release();

	// Create a sink object.
	COPCDataCallback	*pOPCDataCallback=NULL;
	pOPCDataCallback = new COPCDataCallback;
	
	// dwCookie is used as an identifier for the callbacks.
	DWORD dwCookie;
	// Start the advise. Pass the address of the sink to the OPC server.
	// The server will callback into the functions referenced by this pointer
	// after I/O is completed. A unique identifier is assigned to dwCookie.
	r1 = pConnPt->Advise(pOPCDataCallback, &dwCookie);
	if (FAILED(r1)){
		DisplayError("Error attempting to start Advise", r1);
		pConnPt->Release();
		pOPCServer->Release();
		CoUninitialize();
		exit (1);
	}

	IOPCAsyncIO2	 *pOPCAsyncIO2=NULL;
	
	// Get a pointer to the IOPCAsyncIO2 interface
	r1 = pOPCItemMgt->QueryInterface(IID_IOPCAsyncIO2, (void**)&pOPCAsyncIO2);
	if (FAILED(r1)){
		DisplaySystemError("Error attempting to get IOPCAsyncIO2 pointer", r1);
		CoUninitialize();
		exit (1);
	}

	// Set the group subscription mode to inactive.
	r1 = pOPCAsyncIO2->SetEnable(FALSE);
	if (FAILED(r1)){
		DisplayError("Error attempting to set subscription mode", r1);
	}


	HRESULT			*WriteErrors = NULL;
	HRESULT			*ReadErrors = NULL;
	OPCHANDLE *pItemHandles = (OPCHANDLE*)CoTaskMemAlloc(dwCount*sizeof(OPCHANDLE));
	DWORD			dwTransactionId = 0;
	VARIANT *pItemValues = (VARIANT*)CoTaskMemAlloc(dwCount*sizeof(VARIANT));

	for (n=0 ; n < dwCount; n  ){
		//Initialize the variant to be used for writing data to target.
		VariantInit(&pItemValues[n]);
	
		//Set the variant data type.
		pItemValues[n].vt = pAddResults[n].vtCanonicalDataType;
	
		// get handle assigned to item by server and insert it into item handle array
		pItemHandles[n] = pAddResults[n].hServer;
	}


	// Get a pointer to the Group State Management interface. 
	IOPCGroupStateMgt	*pOPCGroupStateMgt;
	r1 = pOPCItemMgt->QueryInterface(IID_IOPCGroupStateMgt, (void**)&pOPCGroupStateMgt);
	if (FAILED(r1)){
		DisplaySystemError("Error attempting to get IOPCGroupStateMgt pointer", r1);
		CoUninitialize();
		exit (1);
	}

	BOOL Done = FALSE;
	HRESULT *StateErrors=NULL;


	// This section of code runs in a loop, allowing the user to enter the following
	// commands:
	//   1. R to perform a single asynchronous read
	//   2. W to perform an asynchronous write
	//   3. T to toggle the subscription mode between active and 
	//      inactive (default)
	//   4. X to exit
	//
	// When the group is active, subscription mode is on. Subscription mode allows the
	// data items to be automatically updated on a change in value.
	// When the group is inactive, subscription mode is off. The data item can be updated
	// via an asynchronous read.

	printf ("\nCommands are performed using the following keystrokes:\n");
	printf ("1. F to refresh data\n");
	printf ("2. R to perform a single asynchronous read\n");
	printf ("3. W to perform an asynchronous write\n");
	printf ("4. T to toggle the subscription mode between active and inactive\n");
	printf ("5. U to change group update rate\n");
	printf ("6. X to exit\n");

	BOOL OnDataChangeActive = FALSE;
	DWORD	dwCancelId;
	
	while(!Done){
		if (kbhit()){

			// Check for character from keyboard.
			c = getch();
			
			switch(c){
			
			// Perform data refresh
			case 'F':
			case 'f':
				DWORD dwCancelID;
				r1 = pOPCAsyncIO2->Refresh2(OPC_DS_CACHE, dwTransactionId  , &dwCancelID);
				if (FAILED(r1)){
					DisplayError("Failed attempting data refresh:", r1);
				}
				break;
			
			// Perform asynchronous write
			case 'W':
			case 'w':
//				char szWriteValue[8];
//				printf("\nEnter the integer value to be written:\n");
//				gets(szWriteValue);
//				pItemValues[0].iVal = atoi(szWriteValue);
				GetWriteData(dwCount, pItemValues);
				
			r1 = pOPCAsyncIO2->Write(dwCount, pItemHandles,
									 pItemValues, dwTransactionId  , &dwCancelId, 
									 &WriteErrors);
			if (FAILED(r1)){
					DWORD dwLastError;
					dwLastError = GetLastError();
					DisplayError("Main:Failed attempting asynchronous write", r1);
					//CoUninitialize();
					//exit (EXIT_FAILURE);
				}
				else if (r1 == S_FALSE){
					if (FAILED(WriteErrors[0])){
						DisplayError("Main:Error writing data", WriteErrors[0]);
						//CoUninitialize();
						//exit(EXIT_FAILURE);
					}
				}
				CoTaskMemFree(WriteErrors);
				break;

			// Perform asynchronous read
			case 'R':
			case 'r':
				r1 = pOPCAsyncIO2->Read(dwCount, pItemHandles, dwTransactionId  , &dwCancelId, &ReadErrors);
				if (FAILED(r1)){
					DWORD dwLastError;
					dwLastError = GetLastError();
					DisplayError("Asynchronous read failed", r1);
				}
				else if (r1 == S_FALSE){
					if (FAILED(ReadErrors[0])){
						DisplayError("Error reading data", ReadErrors[0]);
					}
				}
				CoTaskMemFree(ReadErrors);
				break;
			
			// Toggle the subscription mode between active and inactive
			case 'T':
			case 't':
				if (OnDataChangeActive == TRUE){
					OnDataChangeActive = FALSE;
					printf("\nSubscription is inactive\n");
				}
				else if (OnDataChangeActive == FALSE){
					OnDataChangeActive = TRUE;
					printf("\nSubscription is active\n");
				}
				
				r1 = pOPCAsyncIO2->SetEnable(OnDataChangeActive);
				if (FAILED(r1)){
					DisplayError("Error attempting to set subscription mode", r1);
				}
				break;
			// Change the group update rate
			case 'U':
			case 'u':
				char *errptr, szUserInput[20];
				DWORD dwActualRate, dwUpdateRate;
				errptr = NULL;
				printf("\nEnter a new group update rate in milliseconds\n");
				gets(szUserInput);
				dwUpdateRate = strtoul(szUserInput, &errptr, 10);
				if (*errptr != NULL)
					printf ("Error entering update rate\n");
				else {
					r1 = pOPCGroupStateMgt->SetState(&dwUpdateRate, &dwActualRate, NULL,
													 NULL, NULL, NULL, NULL);
					if (FAILED(r1))
						DisplayError("Error at SetState", r1);
					else {
						printf("the new update rate entered by user is %ld\n", dwUpdateRate);
						printf("the actual rate used by the server is %ld\n", dwActualRate);
					}
				}

				break;

			// Exit the application
			case 'X':
			case 'x':
				printf("\nProgram terminated by user\n");
				Done = TRUE;
				break;
			} //end of switch
		}
		else{
			MSG msg;
			// Message pump. Required to run with COM Single Threaded Apartment
			while(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)){
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		// Go to sleep. Give someone else a chance to run.
		Sleep(1);
	}//end while

	// Using the dwCookie identifier, the Advise callback is turned off.
	if (pConnPt != NULL){
		r1 = pConnPt->Unadvise(dwCookie);
		if (FAILED(r1)){
			DisplayError("Error attempting to release the Advise pointer", r1);
		}
	}

	// remove items from the group
	if ((pOPCItemMgt != NULL) && (pItemHandles != NULL)){
		r1 = pOPCItemMgt->RemoveItems(dwCount, pItemHandles, &pErrors);
		if (FAILED(r1)){
			DisplayError("Failed attempting to remove item(s)", r1);
		}
		else if (r1 == S_FALSE){
			if (FAILED(pErrors[0])){
				DisplayError("Error attempting to remove item", pErrors[0]);
			}
		}
	}

	CoTaskMemFree(pErrors);

	// remove group from the server
	r1 = pOPCServer->RemoveGroup(hServerGroup, TRUE);
	if (FAILED(r1)){
		DisplayError("Failed attempting to remove group", r1);
	}


	// client is responsible for releasing any resources allocated by the server

	// release interfaces
	pConnPt->Release();
	pOPCAsyncIO2->Release();
	pOPCServer->Release();
	pOPCItemMgt->Release();
	pUnkSvr->Release();
	
	// release any memory allocated by server
	CoTaskMemFree(pAddResults);
	
	// uninitialize COM
	CoUninitialize();

	return 0;
}


OPCITEMRESULT *CreateItems(IOPCItemMgt* pOPCItemMgt, OPCITEMDEF *ItemArray, DWORD *dwCount)
{
//
// This function allows the user to create items, validate them and add them 
// to a group.
//
	int n;
	HRESULT			*AddErrors;
	BYTE			*MyBlob=NULL;
	WCHAR			szwItemName[80];
	HRESULT			r1;
	OPCITEMRESULT	*pResults;
	char			szErrorString[80];
	OPCITEMRESULT	*ValidationResults;
	HRESULT			*pErrors=0;

	
	// Create new items.
	printf("\n...Create new items\n\n");

	for (n=0; n < (int)*dwCount; n  ){
		// User enters item names
		BOOL CurrentItemValid=FALSE;
		ItemArray[n].szItemID = (LPWSTR)CoTaskMemAlloc(sizeof(szwItemName));
		while (!CurrentItemValid){
		printf("\nEnter the item number %d in the form\n", n);
		printf("[OPC topic name]item, for example: [MyTopic]theTag\n>");
		_getws(szwItemName);
		// Create the item
		ItemArray[n].szAccessPath = L"\0"; //szwAccessPath
//		ItemArray[n].szItemID = (LPWSTR)CoTaskMemAlloc(sizeof(szwItemName));
		wcscpy(ItemArray[n].szItemID, szwItemName);
		ItemArray[n].bActive = TRUE;
		ItemArray[n].hClient = 0x200   n;
		ItemArray[n].dwBlobSize = 0;
		ItemArray[n].pBlob = NULL;
		ItemArray[n].vtRequestedDataType = VT_EMPTY;
//	}	

		// Validate the item(s) in the group
		r1 = pOPCItemMgt->ValidateItems(1, &ItemArray[n],0, 
							   &ValidationResults, &pErrors);

		// Check for errors
		if (FAILED(r1)){
			DisplayError("Failed attempting to validate item(s)", r1);
		}
		else if (r1 == S_FALSE){
//			for (n=0; n < (int)*dwCount; n  ){
				if (FAILED(*pErrors)){
					sprintf(szErrorString, "Error attempting to validate item %d",n);
					DisplayError(szErrorString, *pErrors);
				}
//			}
		}
		else{
			printf ("Item is valid\n");
			CurrentItemValid = TRUE;
		}
		CoTaskMemFree(pErrors);
		CoTaskMemFree(ValidationResults);
		}
	}
	
	
	// If the items are valid, add them to the group
	r1 = pOPCItemMgt->AddItems(*dwCount, ItemArray, 
							   &pResults, &AddErrors);

	// Check for errors
	if (FAILED(r1)){
		DisplayError("Failed attempting to add items", r1);
		CoTaskMemFree(AddErrors);
		CoTaskMemFree(pResults);
		pResults = NULL;
	}
	else if (r1 == S_FALSE){
		for (n=0; n < (int)*dwCount; n  ){
			if (FAILED(AddErrors[n])){
				sprintf(szErrorString, "Error attempting to add item %d",n);
				DisplayError(szErrorString, AddErrors[n]);
			}
		}
		CoTaskMemFree(AddErrors);
		CoTaskMemFree(pResults);
		pResults = NULL;
	}
	else printf ("\n...Items added to group successfully\n");

	// Free the memory allocated to the item names in ItemArray

	CoTaskMemFree(AddErrors);
//	CoTaskMemFree(pErrors);
//	CoTaskMemFree(ValidationResults);

	for (n=0; n < (int)*dwCount; n  )
		CoTaskMemFree(ItemArray[n].szItemID);

	return pResults;
}

void GetWriteData(DWORD dwCount, VARIANT *pItemValues)
{
	// This function takes user input and assigns the values to OPC items.
	// These values are then written to the target processor.
	// The allowed items are integer and float for this sample.
	
	DWORD n;
	char szWriteValue[16];

	// Prompt for new item values from user
	for (n=0; n < dwCount; n  ){
		if (pItemValues[n].vt == VT_I2){
			printf("Enter the integer value for item %d\n", n);
			gets(szWriteValue);
			pItemValues[n].iVal = atoi(szWriteValue);
		}
		else if (pItemValues[n].vt == VT_R4){
			printf("Enter the float value for item %d\n", n);
			gets(szWriteValue);
			pItemValues[n].fltVal = (float)atof(szWriteValue);
		}
		else printf("Data type not supported by GetWriteData\n");
	}

}

IUnknown *CreateLocalServer(WCHAR *pwszServerName)
{
	HRESULT r1;
	IUnknown *pIUnknown;
	CLSID	Clsid;
	IClassFactory	*pIFactory;


	//Obtain class ID of RSlinx OPC Server from the Prog ID.
	r1 = CLSIDFromProgID(pwszServerName, &Clsid);
	if (FAILED(r1)){
		DisplaySystemError("Error at CLSIDFromProgID", r1);
		CoUninitialize();
		exit (1);
	}
	else{
		printf("found Class ID for RSLinx OPC server\n");
	}

	//Create class factory interface pointer
	r1 = CoGetClassObject(Clsid, CLSCTX_ALL, NULL,
						  IID_IClassFactory, (void**)&pIFactory);
	if (FAILED(r1)){
		DisplaySystemError("Error at CoGetClassObject", r1);
		CoUninitialize();
		exit (1);
	}
	
	// Create an instance of the RSLinx server object and obtain a pointer
	// to the IUnknown interface
	r1 = pIFactory->CreateInstance(NULL, IID_IUnknown,(void**)&pIUnknown);
	if (FAILED(r1)){
		DisplaySystemError("Error attempting to create server object", r1);
		CoUninitialize();
		exit (1);
	}

	// Release the class factory
	pIFactory->Release();

	return pIUnknown;
}

IUnknown *CreateInProcServer(WCHAR *pwszServerName)
{
	HRESULT r1;
	IUnknown *pIUnknown;
	CLSID	Clsid;
	IClassFactory	*pIFactory;


	//Obtain class ID of RSlinx OPC Server from the Prog ID.
	r1 = CLSIDFromProgID(pwszServerName, &Clsid);
	if (FAILED(r1)){
		DisplaySystemError("Error at CLSIDFromProgID", r1);
		return (IUnknown*)NULL;
//		CoUninitialize();
//		exit (1);
	}
	else{
		printf("found Class ID for RSLinx OPC server\n");
	}

	//Create class factory interface pointer
	r1 = CoGetClassObject(Clsid, CLSCTX_INPROC_SERVER, NULL,
						  IID_IClassFactory, (void**)&pIFactory);
	if (FAILED(r1)){
		DisplaySystemError("Error at CoGetClassObject", r1);
		return (IUnknown*)NULL;
		//CoUninitialize();
		//exit (1);
	}
	
	// Create an instance of the RSLinx server object and obtain a pointer
	// to the IUnknown interface
	r1 = pIFactory->CreateInstance(NULL, IID_IUnknown,(void**)&pIUnknown);
	if (FAILED(r1)){
		DisplaySystemError("Error attempting to create server object", r1);
		return (IUnknown*)NULL;
		//CoUninitialize();
		//exit (1);
	}

	// Release the class factory
	pIFactory->Release();

	return pIUnknown;
}

IUnknown *CreateRemoteServer(WCHAR *pwszServerName, WCHAR *pwszComputerName)
{
	HRESULT r1;
	CLSID	Clsid;
	MULTI_QI mqi;
	COSERVERINFO	sin, *sinptr;
	DWORD clsctx;
	
	//Obtain class ID of RSlinx OPC Server from the Prog ID.
	r1 = CLSIDFromProgID(pwszServerName, &Clsid);
	if (FAILED(r1)){
		DisplaySystemError("Error at CLSIDFromProgID", r1);
		CoUninitialize();
		exit (1);
	}
	else{
		printf("found Class ID for RSLinx OPC server\n");
	}

	// Configure server info structure
	//
	if(*pwszComputerName)
	{
		sinptr = &sin;
		sin.dwReserved1 = 0;
		sin.dwReserved2 = 0;
		sin.pwszName = pwszComputerName;
		sin.pAuthInfo = 0;
		clsctx = CLSCTX_ALL;
	} else
	{
		// If NODE is Nul then try local server
		sinptr = 0;		// pointer should be NULL if local
	}

	// set up mqi
	//
	mqi.pIID = &IID_IUnknown;
	mqi.hr = 0;
	mqi.pItf = 0;

	// To use this function, define _WIN32_DCOM in 'Settings'
	r1 = CoCreateInstanceEx(Clsid, NULL, 
		clsctx, sinptr, 1, &mqi);

	if (FAILED(r1) || FAILED(mqi.hr))
	{
		printf("CoCreateInstanceEx - failed for node:%ls ProgID:%ls (%lx)\n", pwszComputerName, pwszServerName, r1);
		DisplaySystemError("at CoInitialize instance", r1);
		DisplaySystemError("at CoInitialize instance", mqi.hr);
		
		return NULL;
	}

	printf("Remote Object (with IUnknown) Created for %ls\n", pwszServerName);
	return (IUnknown*)mqi.pItf;
}


标签: c++ opc PLC

实例下载地址

OPC PLC通讯 示例源码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

第 1 楼 yeming 发表于: 2018-10-04 17:10 10
在VS2013上编译出现很多问题

支持(0) 盖楼(回复)

第 2 楼 yeming 发表于: 2018-10-04 17:13 00
我来说两句...

支持(0) 盖楼(回复)

发表评论

(您的评论需要经过审核才能显示)

查看所有2条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警