diff --git a/Core/ClientSMLSWIG/CSharp/CSharpCallbackByHand.h b/Core/ClientSMLSWIG/CSharp/CSharpCallbackByHand.h index 29a79e7e8a..3192dccb35 100644 --- a/Core/ClientSMLSWIG/CSharp/CSharpCallbackByHand.h +++ b/Core/ClientSMLSWIG/CSharp/CSharpCallbackByHand.h @@ -9,6 +9,11 @@ // that SWIG can't auto generate. // +#ifdef __cplusplus +// We expose the public methods in a DLL with C naming (not C++ mangled names) +extern "C" { +#endif + // __stcall calling convention only applicable to 32-bit Windows #if defined(_WIN32) && !defined(_WIN64) #define STDCALL __stdcall @@ -813,8 +818,9 @@ typedef char const* (STDCALL* ClientMessageCallback)(int eventID, CallbackDataPt // Then from here we need to call back to C# to pass back the message. static const char *RhsEventHandler(sml::smlRhsEventId /*id*/, void* pUserData, sml::Agent* pAgent, char const* pFunctionName, char const* pArgument, int *bufSize, char *buf) { + // Previous result was cached, meaning client should be calling again to get it + // return that result and clear the cache static std::string prevResult; - if ( !prevResult.empty() ) { strncpy( buf, prevResult.c_str(), *bufSize ); @@ -837,6 +843,8 @@ static const char *RhsEventHandler(sml::smlRhsEventId /*id*/, void* pUserData, s // Now try to call back to CSharp std::string res = callback(pData->m_EventID, pData->m_CallbackData, pData->m_Kernel, csharpAgentName, csharpFunctionName, csharpArgument) ; + // Too long to fit in the buffer; cache result and signal client with + // NULL return value to call again with a larger buffer if ( res.length() + 1 > *bufSize ) { *bufSize = res.length() + 1; @@ -852,8 +860,10 @@ static const char *RhsEventHandler(sml::smlRhsEventId /*id*/, void* pUserData, s // Then from here we need to call back to C# to pass back the message. static const char *ClientEventHandler(sml::smlRhsEventId /*id*/, void* pUserData, sml::Agent* pAgent, char const* pClientName, char const* pMessage, int *bufSize, char *buf ) { - static std::string prevResult; + // Previous result was cached, meaning client should be calling again to get it + // return that result and clear the cache + static std::string prevResult; if ( !prevResult.empty() ) { strncpy( buf, prevResult.c_str(), *bufSize ); @@ -876,6 +886,8 @@ static const char *ClientEventHandler(sml::smlRhsEventId /*id*/, void* pUserData // Now try to call back to CSharp std::string res = callback(pData->m_EventID, pData->m_CallbackData, pData->m_Kernel, csharpAgentName, csharpClientName, csharpMessage) ; + // Too long to fit in the buffer; cache result and signal client with + // NULL return value to call again with a larger buffer if ( res.length() + 1 > *bufSize ) { *bufSize = res.length() + 1; @@ -1045,3 +1057,6 @@ SWIGEXPORT bool SWIGSTDCALL CSharp_Kernel_UnregisterForAgentEvent(void* jarg1, i return result ; } +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/Core/ClientSMLSWIG/CSharp/CSharp_sml_ClientInterface.i b/Core/ClientSMLSWIG/CSharp/CSharp_sml_ClientInterface.i index 29f877735d..620af6650a 100644 --- a/Core/ClientSMLSWIG/CSharp/CSharp_sml_ClientInterface.i +++ b/Core/ClientSMLSWIG/CSharp/CSharp_sml_ClientInterface.i @@ -511,12 +511,6 @@ //%newobject sml::Kernel::CreateRemoteConnection; %{ -#ifdef __cplusplus - extern "C" { -#endif #include "CSharpCallbackByHand.h" -#ifdef __cplusplus - } -#endif - %} +%} diff --git a/Core/ClientSMLSWIG/Java/JavaCallbackByHand.h b/Core/ClientSMLSWIG/Java/JavaCallbackByHand.h index 3a1d774129..670e41a90d 100644 --- a/Core/ClientSMLSWIG/Java/JavaCallbackByHand.h +++ b/Core/ClientSMLSWIG/Java/JavaCallbackByHand.h @@ -114,6 +114,11 @@ int jUpdateCallback = pKernel.RegisterForSystemEvent(pKernel, smlEventId.smlEVEN // A native thread cannot be attached simultaneously to two Java VMs. // When a thread is attached to the VM, the context class loader is the bootstrap loader. +#ifdef __cplusplus +// We expose the public methods in a DLL with C naming (not C++ mangled names) +extern "C" { +#endif + #include #include @@ -1103,8 +1108,9 @@ JNIEXPORT bool JNICALL Java_sml_smlJNI_Kernel_1UnregisterForStringEvent(JNIEnv * static const char *RhsEventHandler(sml::smlRhsEventId id, void* pUserData, sml::Agent* pAgent, char const* pFunctionName, char const* pArgument, int *bufSize, char *buf) { + // Previous result was cached, meaning client should be calling again to get it + // return that result and clear the cache static std::string prevResult; - if ( !prevResult.empty() ) { strncpy( buf, prevResult.c_str(), *bufSize ); @@ -1173,6 +1179,8 @@ static const char *RhsEventHandler(sml::smlRhsEventId id, void* pUserData, sml:: jenv->ReleaseStringUTFChars(result, pResult); } + // Too long to fit in the buffer; cache result and signal client with + // NULL return value to call again with a larger buffer if ( resultStr.length() + 1 > *bufSize ) { *bufSize = resultStr.length() + 1; @@ -1189,8 +1197,9 @@ static const char *RhsEventHandler(sml::smlRhsEventId id, void* pUserData, sml:: static const char *ClientMessageHandler(sml::smlRhsEventId id, void* pUserData, sml::Agent* pAgent, char const* pFunctionName, char const* pArgument, int *bufSize, char *buf) { + // Previous result was cached, meaning client should be calling again to get it + // return that result and clear the cache static std::string prevResult; - if ( !prevResult.empty() ) { strncpy( buf, prevResult.c_str(), *bufSize ); @@ -1259,6 +1268,8 @@ static const char *ClientMessageHandler(sml::smlRhsEventId id, void* pUserData, jenv->ReleaseStringUTFChars(result, pResult); } + // Too long to fit in the buffer; cache result and signal client with + // NULL return value to call again with a larger buffer if ( resultStr.length() + 1 > *bufSize ) { *bufSize = resultStr.length() + 1; @@ -1441,3 +1452,7 @@ JNIEXPORT bool JNICALL Java_sml_smlJNI_Kernel_1UnregisterForAgentEvent(JNIEnv *j return result ; } + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/Core/ClientSMLSWIG/Java/Java_sml_ClientInterface.i b/Core/ClientSMLSWIG/Java/Java_sml_ClientInterface.i index dd591e9ef3..b9a27d328d 100644 --- a/Core/ClientSMLSWIG/Java/Java_sml_ClientInterface.i +++ b/Core/ClientSMLSWIG/Java/Java_sml_ClientInterface.i @@ -51,7 +51,7 @@ throw e ; } } - + public final static native long Agent_RegisterForRunEvent(long jarg1, int jarg2, Object jarg3, Object jarg4, Object jarg6); public final static native long Agent_RegisterForProductionEvent(long jarg1, int jarg2, Object jarg3, Object jarg4, Object jarg6); public final static native long Agent_RegisterForPrintEvent(long jarg1, int jarg2, Object jarg3, Object jarg4, Object jarg6, boolean jarg7); @@ -87,26 +87,26 @@ public interface ProductionEventInterface { public void productionEventHandler(int eventID, Object data, Agent agent, String prodName, String instantiation) ; } - - public interface PrintEventInterface { + + public interface PrintEventInterface { public void printEventHandler(int eventID, Object data, Agent agent, String message) ; } - + public interface xmlEventInterface { public void xmlEventHandler(int eventID, Object data, Agent agent, ClientXML xml) ; } - public interface OutputEventInterface { + public interface OutputEventInterface { public void outputEventHandler(Object data, String agentName, String attributeName, WMElement pWmeAdded) ; } - + public interface OutputNotificationInterface { public void outputNotificationHandler(Object data, Agent agent) ; } public long RegisterForRunEvent(smlRunEventId id, RunEventInterface handlerObject, Object callbackData) { return smlJNI.Agent_RegisterForRunEvent(swigCPtr, id.swigValue(), this, handlerObject, callbackData) ;} - + public long RegisterForProductionEvent(smlProductionEventId id, ProductionEventInterface handlerObject, Object callbackData) { return smlJNI.Agent_RegisterForProductionEvent(swigCPtr, id.swigValue(), this, handlerObject, callbackData) ; } @@ -118,7 +118,7 @@ public long RegisterForXMLEvent(smlXMLEventId id, xmlEventInterface handlerObject, Object callbackData) { return smlJNI.Agent_RegisterForXMLEvent(swigCPtr, id.swigValue(), this, handlerObject, callbackData) ; } - + public long RegisterForOutputNotification(OutputNotificationInterface handlerObject, Object callbackData) { return smlJNI.Agent_RegisterForOutputNotification(swigCPtr, this, handlerObject, callbackData) ;} @@ -149,29 +149,29 @@ public void systemEventHandler(int eventID, Object data, Kernel kernel) ; } - public interface UpdateEventInterface { + public interface UpdateEventInterface { public void updateEventHandler(int eventID, Object data, Kernel kernel, int runFlags) ; } - public interface StringEventInterface { + public interface StringEventInterface { public String stringEventHandler(int eventID, Object userData, Kernel kernel, String callbackData) ; } - public interface AgentEventInterface { + public interface AgentEventInterface { public void agentEventHandler(int eventID, Object data, String agentName) ; } - public interface RhsFunctionInterface { + public interface RhsFunctionInterface { public String rhsFunctionHandler(int eventID, Object data, String agentName, String functionName, String argument) ; } - public interface ClientMessageInterface { + public interface ClientMessageInterface { public String clientMessageHandler(int eventID, Object data, String agentName, String functionName, String argument) ; } - + public long RegisterForSystemEvent(smlSystemEventId id, SystemEventInterface handlerObject, Object callbackData) { return smlJNI.Kernel_RegisterForSystemEvent(swigCPtr, id.swigValue(), this, handlerObject, callbackData) ;} - + public boolean UnregisterForSystemEvent(long callbackReturnValue) { return smlJNI.Kernel_UnregisterForSystemEvent(swigCPtr, callbackReturnValue) ;} @@ -183,10 +183,10 @@ public long RegisterForStringEvent(smlStringEventId id, StringEventInterface handlerObject, Object callbackData) { return smlJNI.Kernel_RegisterForStringEvent(swigCPtr, id.swigValue(), this, handlerObject, callbackData) ;} - + public boolean UnregisterForStringEvent(long callbackReturnValue) { return smlJNI.Kernel_UnregisterForStringEvent(swigCPtr, callbackReturnValue) ;} - + public long RegisterForAgentEvent(smlAgentEventId id, AgentEventInterface handlerObject, Object callbackData) { return smlJNI.Kernel_RegisterForAgentEvent(swigCPtr, id.swigValue(), this, handlerObject, callbackData) ; } @@ -212,7 +212,7 @@ smlJNI.Kernel_ShutdownInternal(swigCPtr, this); delete() ; } - + // Allow a user to avoid deleting the kernel object immediately, if they have some special reason. public void ShutdownNoDelete() { @@ -230,20 +230,20 @@ public void addAttribute(String attributeName, String valueName) { AddAttribute(attributeName, valueName) ; } - + public String getAttributeThrows(String name) throws Exception { String value = GetAttribute(name) ; if (value == null) - throw new Exception("Could not find attribute " + name + " while parsing XML document") ; + throw new Exception("Could not find attribute " + name + " while parsing XML document") ; return value ; - } + } public int getAttributeIntThrows(String name) throws Exception { String val = getAttributeThrows(name) ; int intVal = Integer.parseInt(val) ; return intVal ; } - + private long GetCPtrAndDisown(ElementXML pChild) { pChild.swigCMemOwn = false; return ElementXML.getCPtr(pChild); @@ -275,11 +275,5 @@ %{ -#ifdef __cplusplus -extern "C" { -#endif #include "JavaCallbackByHand.h" -#ifdef __cplusplus -} -#endif -%} \ No newline at end of file +%} diff --git a/Core/ClientSMLSWIG/Python/Python_sml_ClientInterface.i b/Core/ClientSMLSWIG/Python/Python_sml_ClientInterface.i index b01fa34561..fb511cd42b 100644 --- a/Core/ClientSMLSWIG/Python/Python_sml_ClientInterface.i +++ b/Core/ClientSMLSWIG/Python/Python_sml_ClientInterface.i @@ -284,8 +284,9 @@ const char *PythonRhsEventCallback(sml::smlRhsEventId id, void* pUserData, sml::Agent* pAgent, char const* pFunctionName, char const* pArgument, int *bufSize, char *buf) { + // Previous result was cached, meaning client should be calling again to get it + // return that result and clear the cache static std::string prevResult; - if ( !prevResult.empty() ) { strncpy( buf, prevResult.c_str(), *bufSize ); @@ -318,6 +319,8 @@ PyGILState_Release(gstate); /* Release the thread. No Python API allowed beyond this point. */ + // Too long to fit in the buffer; cache result and signal client with + // NULL return value to call again with a larger buffer if ( res.length() + 1 > *bufSize ) { *bufSize = res.length() + 1; @@ -331,8 +334,9 @@ const char *PythonClientMessageEventCallback(sml::smlRhsEventId id, void* pUserData, sml::Agent* pAgent, char const* pClientName, char const* pMessage, int *bufSize, char *buf) { + // Previous result was cached, meaning client should be calling again to get it + // return that result and clear the cache static std::string prevResult; - if ( !prevResult.empty() ) { strncpy( buf, prevResult.c_str(), *bufSize ); @@ -364,6 +368,8 @@ PyGILState_Release(gstate); /* Release the thread. No Python API allowed beyond this point. */ + // Too long to fit in the buffer; cache result and signal client with + // NULL return value to call again with a larger buffer if ( res.length() + 1 > *bufSize ) { *bufSize = res.length() + 1; diff --git a/Core/ClientSMLSWIG/Tcl/Tcl_sml_ClientInterface.i b/Core/ClientSMLSWIG/Tcl/Tcl_sml_ClientInterface.i index d7dc475568..3744f4b327 100644 --- a/Core/ClientSMLSWIG/Tcl/Tcl_sml_ClientInterface.i +++ b/Core/ClientSMLSWIG/Tcl/Tcl_sml_ClientInterface.i @@ -165,8 +165,9 @@ const char *TclRhsEventCallback(sml::smlRhsEventId, void* pUserData, sml::Agent* pAgent, char const* pFunctionName, char const* pArgument, int *bufSize, char *buf) { + // Previous result was cached, meaning client should be calling again to get it + // return that result and clear the cache static std::string prevResult; - if ( !prevResult.empty() ) { strncpy( buf, prevResult.c_str(), *bufSize ); @@ -197,6 +198,8 @@ std::string sres = Tcl_GetString(res); + // Too long to fit in the buffer; cache result and signal client with + // NULL return value to call again with a larger buffer if ( sres.length() + 1 > *bufSize ) { *bufSize = sres.length() + 1; @@ -211,8 +214,9 @@ const char *TclClientMessageEventCallback(sml::smlRhsEventId, void* pUserData, sml::Agent* pAgent, char const* pClientName, char const* pMessage, int *bufSize, char *buf) { + // Previous result was cached, meaning client should be calling again to get it + // return that result and clear the cache static std::string prevResult; - if ( !prevResult.empty() ) { strncpy( buf, prevResult.c_str(), *bufSize ); @@ -244,6 +248,8 @@ std::string sres = Tcl_GetString(res); + // Too long to fit in the buffer; cache result and signal client with + // NULL return value to call again with a larger buffer if ( sres.length() + 1 > *bufSize ) { *bufSize = sres.length() + 1;