Git Product home page Git Product logo

opc-client-x64's Introduction

Description

  • An object oriented OPC DA Client SDK/ToolKit written in C++, Both X86/X64 supported, implementing the OPC DA specification version 2.05A
  • New Features (Compare with the original version)
    • Build with x64 project.
    • Build with MFC.
    • Multithread supported.
    • Connect to server with CLSID.(Hasn't tested)

Notes

Current master branch contains a huge bug fixes commit from PR#14, which might introduce some new bugs. If the master branch went wrong, you may check release 0.4.1 as a backup.

Basic Guide

  • Install OPC Core Component x64 is NECESSARY if you want to build x64 project, I bundled the 3.0.105.1 version (seems more popular).
  • You can test the Toolkit with MatrikonOPC Simulation Server.
    • You can get it free at offical site after reg.
    • Start OPC Simulation Server, then build project. Run the demo, input hostname, then input server ID, it should work.
    • If you were to commit a issue, you should give a code sample with the Simulation Server. Since this is the only env we can reproduce the error.
  • I advice you to use hostname instead of IP address for reasons below.
    • If you want to access OPC by IP, you have to enable RemoteRegistry service in services.msc
    • Also , for UAC problem after Vista, your program must run as admin to avoid some issue.
  • There is a convenience wrapper class that may help you connect local server easier.

Advanced Guide

  • Multi - Thread Programing Guide
    • Call COPCCLint::initand COPCClinet::stop in every thread. There are two method to init, in one application, different thread could use different method.
      • You can call COPCClient::init(MULTITHREADED) to init thread OLE, then the COPCxxx created in the thread could be accessed from other thread that is also inited with MULTITHREADED.
      • You can call COPCClient::init() to init thread OLE, but all COPCxxx created in the thread can't be accessed from different thread.
    • Attention: If you are using anything related to MFC GUI, you MUST use COPCClient::init() in main thread (the UI thread) . (See MSDN) .

Detail & ChangeLog

  • Date: 2024-06-18

    • Thanks for kumajaya, the project has been switched to CMake PR#18, you can build it with CMake now.
  • Date: 2021-10-10

    • Thanks for wolfgang.griech ([email protected]), who contributed a huge bug fixes PR#14 that may fix many issues in this project.
  • Date: 2017-07-07

    • Thanks for mzillgith, now the project can connect to remote server with CLSID.(It hasn't been tested)
  • Date: 2017-04-13

    • Fix a string conversion bug which might lead stack overflow
    • Add a convenience class to connect local server in sync I/O mode
        // connect local server
        LocalSyncOPCCLient* client = new LocalSyncOPCCLient;
        client->Init();
        if (client->Connect("Matrikon.OPC.Simulation.1"))
        {
            // sync write and sync read
            client->WriteUint16("Bucket Brigade.UInt2", 998);
            std::cout << client->ReadUint16("Bucket Brigade.UInt2");
    
            // disconnect and stop
            client->DisConnect();
            client->Stop();
            delete client;
        }
    
    • You could rewrite or override the member function IsOPCConnectedPLC() to make connection more safety
    • You could rewrite or override the member function ItemNameFilter(std::string) to avoid adding useless items
    • Since there are too many Variant type, I only add three basic I/O functions as a guidence, it should help you to add what you need
  • Date:2016-12-13

    • Thanks for Tom Loya's contribution, now the project can work in a multi-threaded environment. You should call COPCClient::init() and COPCClient::stop() in every thread.
  • Date:2016-07-01

    • this std branch tries to move every ATL to STL.
    • the static .lib now works for MFC too.
  • Date:2016-05-31

    • Modified from X86 Version OPC Client 0.4a by beharrell
    • Add some Hint info
    • X64 Version uses includes files form OPC Core Component 3.0.106.

opc-client-x64's People

Contributors

edimetia3d avatar gc87 avatar kumajaya avatar mzillgith avatar tomloya avatar wolfganggriech avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opc-client-x64's Issues

Crash On Listing too many items

In
void COPCServer::getItemNames(std::vectorstd::string & opcItemNames)

cycle:
while((result = iEnum->Next(1, &str, &strSize)) == S_OK)
{
WCHAR * fullName;
result = iOpcNamespace->GetItemID(str, &fullName);
if (SUCCEEDED(result)){
USES_CONVERSION;
char * cStr = OLE2T(fullName);
//char * cStr = OLE2T(str);
//printf("Adding %s\n", cStr);
opcItemNames.push_back(cStr);
COPCClient::comFree(fullName);
}
COPCClient::comFree(str);
}

char * cStr = OLE2T(fullName); allocates memory on stack where it is not freed until we exit function. Since it is called in While loop it will cause stack overflow and crash if there is too many items to list,

My workaround was to create wrapper function around OLE2T which moves data to heap.

Error with Object member variable of type std::string passed to Connect function.

Snippet below fails with error: 80040154 with a "Failed sz: Class ID String" error. I explored a bit but didn't find anything worth mentioning.

(**Object** passed into function)
string servername = ""; // connect to local server
servername = Object->OPCDA_servername; //server name holds "Matrikon.OPC.Simulation.1"
//servername = "Matrikon.OPC.Simulation.1";
client->Init();
if (!client->Connect(servername)) {}

Passing in the commented servername variable it works fine.

Confusion about license

Hi,
I am confused about the license of the project. Whilst the source code files tell it is LGPL the license.txt file tells it is GPLv3. As I understood the GPL it is ok to convert the license from LGPL to GPL but not the other way around. So my question is was this change to GPLv3 intended. With GPLv3 I cannot use it in my project.

Multi-threading issue in COPCClient.cpp

The old code that this was created from used CoInitalizeEx instead of CoInitialize. Also, there was protection around calling CoGetMalloc. I introduced a change to reinstate the original use of init() and stop() (though named differently) in a way that makes the client's usable in a multi-threaded situation. The init() function currently throws an error when being called from different threads, and also throws an error if you don't call it within each thread. The fix that I have put in (unfortunately over 2 commits) makes this work in a multi-threaded environment. I was using 20 threads to read/write values to/from the OPC server with my proposed change.

Remote connect problem

Hi,
I have a problem connecting to the Matrikon simulation server with the OPCClientDemo. The local connect works fine but the remote connect doesn't work. After showing the remote servers correctly and selecting the desired server the function GetCLSIDFromRemoteRegistry fails. It seems the RegQueryValueEx call returns only garbage and the CLSIDFromString call fails. Then later throwing an exception in makeRemoteObject.

Does anybody have an idea what might be the reason? From wireshark it seems that the remote registry access works.

I wonder why the remote registry access is required at all. When using some other clients (e.g. Softing demo client) the connection works also without using remote registry. I guess they are using the OpcEnum.exe for getting the clsid?

This project is no longer developed

Since I am not an expert in windows programming, the problems in this project have been beyond my ability, I can hardly contribute more to this project.
And also, I am doing some other things now, which are not related to the automation system.
So I couldn't put more energy into this project, only Pull Request will be handled in the future.

Can't make x64 work

I'm trying to run OPCClientDemo in x64 mode but it fails in getListOfDAServers() when it calls iCatInfo->EnumClassesOfCategories().
I have OPC Core Components Redistributable (x64) installed. Looking into the registry, I can only find OpcEnum.exe installed in C:\Windows\SysWOW64. Is this right? Am I missing something?
This works fine in Win32 mode...~
Thanks in advance!

Listing/Connecting to Local OPC Server (Kepware) not working on 64-bit version

Hey guys,
I was using the demo (64-bit compilation) with no issues when listing/connecting to remote OPC servers. Now that I need to list the local servers and connect to one of them, I always get:

  • No servers listed, when "iCatInfo->EnumClassesOfCategories(1, Implist, 0, NULL, &iEnum);" is called;
  • "REGDB_E_CLASSNOTREG Class not registered" (0x80040154), if I ignore the list and force try to connect to a given server (specifically when I call iUnknown->QueryInterface(IID_IOPCServer, (void**)&iOpcServer);).

If I compile everything on 32-bit, everything works flawlessly.

I'm on a Windows 7 64-bit with KepWare 5.11. I've also installed OPC Core Component 3.0.105.1 and then moved to 3.0.106 to try solving the issue, but no luck.

Are you guys facing the same issues on a 64-bit system? Any guesses on what may be wrong?

REGDB_E_CLASSNOTREG for CoGetClassObject

I can get the server list successfully.
But then connect this, use the method "result = CoGetClassObject(clsid, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (void**)&iClassFactory);"
then will get the error REGDB_E_CLASSNOTREG.
By the way, I just create a BECKHOFF.TwinCATOpcServerDA

Problem writing string

Hi everybody,

I have read/write access to a string variable. It's a VT_BSTR.
Reading works fine, I have issues with writing.

First question is: how do I know how many charachters (or bytes) I'm allowed to write, if I didn't get any specs in advance?

Second: How do I make use of all the space I have available?
I ask this because when the string holds, e.g., 10 wchars, I can only write 10 or less.
Using Matrikon OPC I can write all the characters number the PLC developer told me.
My code so far:

std::wstring str(L"The string I want to write");
OPCItemData data;
var.pItem->readSync(data, OPC_DS_DEVICE);
wcscpy_s(data.vDataValue.bstrVal, 64, str.c_str()); // I know I have 64 wchars available
var.pItem->writeSync(data.vDataValue);

"var" is a struct I created:

struct VARIABILE  
{  
	std::string Nome;  
	COPCItem* pItem;  
	VARTYPE tipo;  
};

The above code works well only if the string already holds more than str.length(), otherwise the string gets truncated (and I fear I might be overwriting memory areas somewhere).

Any help is appreciated.

not reading/writing items on 64 bit version

the problem I think is that 64 bit system uses 64 bit pointers so the items are not correctly addressed
COPCItem * item = (COPCItem *)itemState[i].hClient;
COPCItem pointer size is 64 bit but hClient is DWORD or 32 bit
something similar is for
CTransaction & trans = *(CTransaction *)Transid;
do you already have any solution for this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.