Reuse of an overloaded operator
-
I am using a C++ dll that overloads an operator in my project, and I want to reuse that overloaded operator in the qt project. Is there a way to do so?
This is what I 've tried but it doesn't work:
typedef istream (*FctPrtp)(istream, Vector::DBC::Network);
FctPrtp op = (FctPrtp) QLibrary::resolve("link to my .dll file", "operator>>");this is the prototype in the C++ header:
VECTOR_DBC_EXPORT std::istream & operator>>(std::istream & is, Network & network);
Thanks in advance. -
I am using a C++ dll that overloads an operator in my project, and I want to reuse that overloaded operator in the qt project. Is there a way to do so?
This is what I 've tried but it doesn't work:
typedef istream (*FctPrtp)(istream, Vector::DBC::Network);
FctPrtp op = (FctPrtp) QLibrary::resolve("link to my .dll file", "operator>>");this is the prototype in the C++ header:
VECTOR_DBC_EXPORT std::istream & operator>>(std::istream & is, Network & network);
Thanks in advance.@abdelilah
I admit I don't know. But since QFunctionPointer QLibrary::resolve(const char *symbol) states:The symbol must be exported as a C function from the library. This means that the function must be wrapped in an extern "C" if the library is compiled with a C++ compiler
are you sure it would accept a C++ overloaded operator like this?
Additionally, usually you provide a function name to
resolve()
. You are attempting to supply an "overload operator". Since your call only mentions the DLL file path andoperator>>
, I can't see how that principle would work, how would it even know what class name you are asking about?You/someone may know better than I, but I don't think you can begin to do this for a C++ class or overloaded operator. Isn't it for simple C functions only, and not for class methods? You wouldn't even be able to call it on a C++ class instance/object.
-
@abdelilah
I admit I don't know. But since QFunctionPointer QLibrary::resolve(const char *symbol) states:The symbol must be exported as a C function from the library. This means that the function must be wrapped in an extern "C" if the library is compiled with a C++ compiler
are you sure it would accept a C++ overloaded operator like this?
Additionally, usually you provide a function name to
resolve()
. You are attempting to supply an "overload operator". Since your call only mentions the DLL file path andoperator>>
, I can't see how that principle would work, how would it even know what class name you are asking about?You/someone may know better than I, but I don't think you can begin to do this for a C++ class or overloaded operator. Isn't it for simple C functions only, and not for class methods? You wouldn't even be able to call it on a C++ class instance/object.
Hi @JonB,
I don't really know how to do this with a C++ struct's method, I only see that it works with a simple C function, then I tried to apply it with that method.
I searched, but I can't find anything that matches to what I'm looking for, If you know any tips for that, I would be greetful. -
Hi @JonB,
I don't really know how to do this with a C++ struct's method, I only see that it works with a simple C function, then I tried to apply it with that method.
I searched, but I can't find anything that matches to what I'm looking for, If you know any tips for that, I would be greetful.@abdelilah
I thought I did reply, and quoted from the docs. You can't use it for a C++ class/method, only for a plain C function.So you would need to write a "wrapper", free function in C to call, passing it your instance as one of the parameters, which in turn would call the appropriate C++ method on the instance pointer. But I don't think you can do that, C code can't call C++ code like this, I think. Googling
call C++ from C function
confirms this. I don't think you can do it, or it's not worth what you would need to write. Unless someone knows better? -
Well, theoretically you should be able to also call C++ methods from C. The C++ compiler mangles the names based on its arguments and context to make them unique for the linker. If you know the mangled name you could actually use this. However, the name mangling is not standardized and different compilers do it differently on different platforms. Even though in theory it is possible, don't go down that route.
Just stick to writing a wrapper function with
extern "C"
as already suggested. C is the most common denominator between all programming languages. For interfacing everything falls back to C. The linker used to link C++ is based on C calling conventions. DLLs are based on C calling conventions. Under the hood C dictates how everything is done. -
Well, theoretically you should be able to also call C++ methods from C. The C++ compiler mangles the names based on its arguments and context to make them unique for the linker. If you know the mangled name you could actually use this. However, the name mangling is not standardized and different compilers do it differently on different platforms. Even though in theory it is possible, don't go down that route.
Just stick to writing a wrapper function with
extern "C"
as already suggested. C is the most common denominator between all programming languages. For interfacing everything falls back to C. The linker used to link C++ is based on C calling conventions. DLLs are based on C calling conventions. Under the hood C dictates how everything is done.@SimonSchroeder
I am interested: even if the OP knew the mangled C++ name somehow, as I wrote given that this is an operator overload which works on an instance of some C++ class, how would C code run a member method on an instance? Are you saying thatsomeInstance->someMethod()
would work from C, not C++, code? Also, whensomeInstance
was passed as a parameter from the C++ to C, what type would you declare it as to receive in the C? You can't use the C++ type. So you'd probably have to declare it asvoid *
. In that case, how would you then manage to compile any kind ofsomeInstance->someMethod()
from C, it would not be able to resolve it? -
This post is deleted!
-
Hi @JonB,
I don't really know how to do this with a C++ struct's method, I only see that it works with a simple C function, then I tried to apply it with that method.
I searched, but I can't find anything that matches to what I'm looking for, If you know any tips for that, I would be greetful.@abdelilah I guess it would help if you could state again what you actually want to achieve in the broader scope. To extend a bit on what others already have written:
The canonical way to use C++ and C is to have a header file that declares the functions, and have the implementation in a .cpp file. If you want to share functions across dll's , it's usually enough to just share the header file (barring some Windows export magic flags). The linker and - at runtime - the operating system will then figure out the right caller/callee path when the application is loaded.
Using features like QLibrary::resolve is only needed and useful if you somehow dynamically have to load a .dll , while the program is running. Typical case for this is different plugins. But in this case you typically just use a C function, as the main benefit of operator<<() - the compile time resolution - does not work anyhow.
-
Hi and thank you all for your response.
Here is a clarification of the actual situation: I use a DLL in a qt project, the DLL overload an operator (>>), and I'm looking for a way to use that operator in Qt.
The Library is written in C++, and I should use it as it is without changing anything because it will be really hard, it's not a small library.
here is the .h which contains the declaration of the overloading:
/*- Copyright (C) 2013-2019 Tobias Lorenz.
- Contact: tobias.lorenz@gmx.net
- This file is part of Tobias Lorenz's Toolkit.
- Commercial License Usage
- Licensees holding valid commercial licenses may use this file in
- accordance with the commercial license agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Tobias Lorenz.
- GNU General Public License 3.0 Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
*/
#pragma once
#include <Vector/DBC/platform.h>
#include <cstdint>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>#include <Vector/DBC/Attribute.h>
#include <Vector/DBC/AttributeDefinition.h>
#include <Vector/DBC/AttributeRelation.h>
#include <Vector/DBC/BitTiming.h>
#include <Vector/DBC/EnvironmentVariable.h>
#include <Vector/DBC/Message.h>
#include <Vector/DBC/Node.h>
#include <Vector/DBC/SignalType.h>
#include <Vector/DBC/ValueDescriptions.h>
#include <Vector/DBC/ValueTable.h>#include <Vector/DBC/vector_dbc_export.h>
namespace Vector {
namespace DBC {/**
-
Network
/
struct VECTOR_DBC_EXPORT Network {
/* successfully parsed */
bool successfullyParsed { false };/** Version (VERSION) */
std::string version {};/** New Symbols (NS) */
std::vectorstd::string newSymbols {};/** Bit Timing (BS) */
BitTiming bitTiming {};/** Nodes (BU) */
std::map<std::string, Node> nodes {};/** Value Tables (VAL_TABLE) */
std::map<std::string, ValueTable> valueTables {};/** Messages (BO) and Signals (SG) */
std::map<uint32_t, Message> messages {};/* Message Transmitters (BO_TX_BU) */
// moved to Message (BO)/** Environment Variables (EV) */
std::map<std::string, EnvironmentVariable> environmentVariables {};/* Environment Variables Data (ENVVAR_DATA) */
// moved to Environment Variables (EV)/** Signal Types (SGTYPE, obsolete) */
std::map<std::string, SignalType> signalTypes {};/** Comments (CM) */
std::string comment {}; // for network
// moved to Node (BU) for nodes
// moved to Message (BO) for messages
// moved to Signal (SG) for signals
// moved to Environment Variable (EV) for environment variables/**
- Attribute Definitions (BA_DEF) and
- Attribute Definitions for Relations (BA_DEF_REL)
*/
std::map<std::string, AttributeDefinition> attributeDefinitions {};
/* Sigtype Attr List (?, obsolete) */
/**
- Attribute Defaults (BA_DEF_DEF) and
- Attribute Defaults for Relations (BA_DEF_DEF_REL)
*/
std::map<std::string, Attribute> attributeDefaults {};
/** Attribute Values (BA) */
std::map<std::string, Attribute> attributeValues {}; // for network
// moved to Node (BU) for nodes
// moved to Message (BO) for messages
// moved to Signal (SG) for signals
// moved to Environment Variable (EV) for environment variables/** Attribute Values on Relations (BA_REF) */
std::map<std::string, AttributeRelation> attributeRelationValues {};/* Value Descriptions (VAL) */
// moved to Signals (BO) for signals
// moved to EnvironmentVariable (EV) for environment variables/* Category Definitions (CAT_DEF, obsolete) */
/* Categories (CAT, obsolete) */
/* Filters (FILTER, obsolete) */
/* Signal Type Refs (SGTYPE, obsolete) */
// moved to Signal (SG)/* Signal Groups (SIG_GROUP) */
// moved to Message (BO)/* Signal Extended Value Types (SIG_VALTYPE, obsolete) */
// moved to Signal (SG)/* Extended Multiplexors (SG_MUL_VAL) */
// moved to Signal (SG)
};
VECTOR_DBC_EXPORT std::ostream & operator<<(std::ostream & os, const Network & network);
VECTOR_DBC_EXPORT std::istream & operator>>(std::istream & is, Network & network);}
}NOTE: it works completely fine when I use it in a C++ console app in Visual studio.
Thank you in advance. -
Hi and thank you all for your response.
Here is a clarification of the actual situation: I use a DLL in a qt project, the DLL overload an operator (>>), and I'm looking for a way to use that operator in Qt.
The Library is written in C++, and I should use it as it is without changing anything because it will be really hard, it's not a small library.
here is the .h which contains the declaration of the overloading:
/*- Copyright (C) 2013-2019 Tobias Lorenz.
- Contact: tobias.lorenz@gmx.net
- This file is part of Tobias Lorenz's Toolkit.
- Commercial License Usage
- Licensees holding valid commercial licenses may use this file in
- accordance with the commercial license agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Tobias Lorenz.
- GNU General Public License 3.0 Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
*/
#pragma once
#include <Vector/DBC/platform.h>
#include <cstdint>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>#include <Vector/DBC/Attribute.h>
#include <Vector/DBC/AttributeDefinition.h>
#include <Vector/DBC/AttributeRelation.h>
#include <Vector/DBC/BitTiming.h>
#include <Vector/DBC/EnvironmentVariable.h>
#include <Vector/DBC/Message.h>
#include <Vector/DBC/Node.h>
#include <Vector/DBC/SignalType.h>
#include <Vector/DBC/ValueDescriptions.h>
#include <Vector/DBC/ValueTable.h>#include <Vector/DBC/vector_dbc_export.h>
namespace Vector {
namespace DBC {/**
-
Network
/
struct VECTOR_DBC_EXPORT Network {
/* successfully parsed */
bool successfullyParsed { false };/** Version (VERSION) */
std::string version {};/** New Symbols (NS) */
std::vectorstd::string newSymbols {};/** Bit Timing (BS) */
BitTiming bitTiming {};/** Nodes (BU) */
std::map<std::string, Node> nodes {};/** Value Tables (VAL_TABLE) */
std::map<std::string, ValueTable> valueTables {};/** Messages (BO) and Signals (SG) */
std::map<uint32_t, Message> messages {};/* Message Transmitters (BO_TX_BU) */
// moved to Message (BO)/** Environment Variables (EV) */
std::map<std::string, EnvironmentVariable> environmentVariables {};/* Environment Variables Data (ENVVAR_DATA) */
// moved to Environment Variables (EV)/** Signal Types (SGTYPE, obsolete) */
std::map<std::string, SignalType> signalTypes {};/** Comments (CM) */
std::string comment {}; // for network
// moved to Node (BU) for nodes
// moved to Message (BO) for messages
// moved to Signal (SG) for signals
// moved to Environment Variable (EV) for environment variables/**
- Attribute Definitions (BA_DEF) and
- Attribute Definitions for Relations (BA_DEF_REL)
*/
std::map<std::string, AttributeDefinition> attributeDefinitions {};
/* Sigtype Attr List (?, obsolete) */
/**
- Attribute Defaults (BA_DEF_DEF) and
- Attribute Defaults for Relations (BA_DEF_DEF_REL)
*/
std::map<std::string, Attribute> attributeDefaults {};
/** Attribute Values (BA) */
std::map<std::string, Attribute> attributeValues {}; // for network
// moved to Node (BU) for nodes
// moved to Message (BO) for messages
// moved to Signal (SG) for signals
// moved to Environment Variable (EV) for environment variables/** Attribute Values on Relations (BA_REF) */
std::map<std::string, AttributeRelation> attributeRelationValues {};/* Value Descriptions (VAL) */
// moved to Signals (BO) for signals
// moved to EnvironmentVariable (EV) for environment variables/* Category Definitions (CAT_DEF, obsolete) */
/* Categories (CAT, obsolete) */
/* Filters (FILTER, obsolete) */
/* Signal Type Refs (SGTYPE, obsolete) */
// moved to Signal (SG)/* Signal Groups (SIG_GROUP) */
// moved to Message (BO)/* Signal Extended Value Types (SIG_VALTYPE, obsolete) */
// moved to Signal (SG)/* Extended Multiplexors (SG_MUL_VAL) */
// moved to Signal (SG)
};
VECTOR_DBC_EXPORT std::ostream & operator<<(std::ostream & os, const Network & network);
VECTOR_DBC_EXPORT std::istream & operator>>(std::istream & is, Network & network);}
}NOTE: it works completely fine when I use it in a C++ console app in Visual studio.
Thank you in advance.@abdelilah Why don't you simply link against that library instead of loading it dynamically using QLibrary::resolve?
-
@abdelilah Why don't you simply link against that library instead of loading it dynamically using QLibrary::resolve?
-
@abdelilah
Do you have any comment to make on my answers? Which boil down to:- You can't call C++ from C.
- You can't call a C++ method instance from C on an instance passed from C++ to C.
- You can't call a C++ function directly because you don't know what mangled name to look for (e.g. what did your
FctPrtp op = (FctPrtp) QLibrary::resolve("link to my .dll file", "operator>>");
return forop
?).
Just wondering :)
Is there a way to do so?
Will be interesting to see.....