Add loadable module support for ms Visual C++ and fix visual studio specific type identification problems, (while making the C++ more correct)

This commit is contained in:
Jason Turner
2009-09-07 17:05:57 +00:00
parent 7e3127549f
commit 798908f127
10 changed files with 347 additions and 12 deletions

View File

@@ -181,7 +181,7 @@ namespace chaiscript
// Both t and t.x share the same memory location, but do not represent // Both t and t.x share the same memory location, but do not represent
// objects of the same type. // objects of the same type.
if (itr != m_ptrs.end() if (itr != m_ptrs.end()
&& itr->second.m_type_info.m_bare_type_info == data->m_type_info.m_bare_type_info) && type_info_bare_equals(itr->second.m_type_info, data->m_type_info))
{ {
(*data) = (itr->second); (*data) = (itr->second);
} }

View File

@@ -416,7 +416,7 @@ namespace chaiscript
itr != m_types.end(); itr != m_types.end();
++itr) ++itr)
{ {
if (itr->second.m_bare_type_info == ti.m_bare_type_info) if (type_info_bare_equals(itr->second, ti))
{ {
return itr->first; return itr->first;
} }

View File

@@ -92,9 +92,9 @@ namespace chaiscript
const Type_Info &ti = types[1]; const Type_Info &ti = types[1];
if (!ti.m_bare_type_info || !(vals[0].get_type_info().m_bare_type_info) if (!ti.m_bare_type_info || !(vals[0].get_type_info().m_bare_type_info)
|| (*ti.m_bare_type_info) == (*user_type<Boxed_Value>().m_bare_type_info) || type_info_bare_equals(ti, user_type<Boxed_Value>())
|| (*ti.m_bare_type_info) == (*user_type<Boxed_POD_Value>().m_bare_type_info) || type_info_bare_equals(ti, user_type<Boxed_POD_Value>())
|| (*vals[0].get_type_info().m_bare_type_info) == (*ti.m_bare_type_info)) || type_info_bare_equals(vals[0].get_type_info(), ti))
{ {
return true; return true;
} else { } else {

View File

@@ -65,7 +65,8 @@ namespace chaiscript
bool operator==(const Type_Info &ti) const bool operator==(const Type_Info &ti) const
{ {
return ti.m_type_info == m_type_info; return ti.m_type_info == m_type_info
|| (ti.m_type_info && m_type_info && *ti.m_type_info == *m_type_info);
} }
bool m_is_const; bool m_is_const;
@@ -144,6 +145,20 @@ namespace chaiscript
return detail::Get_Type_Info<T>::get(); return detail::Get_Type_Info<T>::get();
} }
bool type_info_bare_equals(const Type_Info &l, const Type_Info &r)
{
if (l.m_bare_type_info == 0
&& r.m_bare_type_info == 0)
{
return true;
} else if (l.m_bare_type_info == 0
|| r.m_bare_type_info == 0)
{
return false;
} else {
return *(l.m_bare_type_info) == *(r.m_bare_type_info);
}
}
} }

View File

@@ -9,7 +9,14 @@
#include <exception> #include <exception>
#include <fstream> #include <fstream>
#ifdef _POSIX_VERSION
#include <dlfcn.h> #include <dlfcn.h>
#else
#ifdef _MSC_VER
#include <Windows.h>
#endif
#endif
#include "chaiscript_prelude.hpp" #include "chaiscript_prelude.hpp"
#include "chaiscript_parser.hpp" #include "chaiscript_parser.hpp"
@@ -56,6 +63,10 @@ namespace chaiscript
DLSym(DLModule &t_mod, const std::string &t_symbol) DLSym(DLModule &t_mod, const std::string &t_symbol)
: m_symbol(reinterpret_cast<T>(dlsym(t_mod.m_data, t_symbol.c_str()))) : m_symbol(reinterpret_cast<T>(dlsym(t_mod.m_data, t_symbol.c_str())))
{ {
if (!m_symbol)
{
throw load_module_error(dlerror());
}
} }
T m_symbol; T m_symbol;
@@ -75,9 +86,109 @@ namespace chaiscript
DLSym<Create_Module_Func> m_func; DLSym<Create_Module_Func> m_func;
}; };
#else #else
#ifdef _MSC_VER
std::string GetErrorMessage(DWORD err)
{
LPSTR lpMsgBuf = 0;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
lpMsgBuf,
0, NULL );
std::string retval;
/*
int bsz = WideCharToMultiByte(codepage,
0,
pw,-1,
0,0,
0,0);
if (bsz > 0) {
char p[bsz];
int rc = WideCharToMultiByte(codepage,
0,
pw,-1,
p,bsz,
0,0);
if (rc != 0) {
p[bsz-1] = 0;
retval = p;
}
}
*/
if (lpMsgBuf)
{
retval = lpMsgBuf;
} else {
retval = "Unknown error occured";
}
LocalFree(lpMsgBuf);
return retval;
}
struct Loadable_Module struct Loadable_Module
{ {
struct DLModule
{
DLModule(const std::string &t_filename)
: m_data(LoadLibrary(t_filename.c_str()))
{
if (!m_data)
{
throw load_module_error(GetErrorMessage(GetLastError()));
}
}
~DLModule()
{
FreeLibrary(m_data);
}
HMODULE m_data;
};
template<typename T>
struct DLSym
{
DLSym(DLModule &t_mod, const std::string &t_symbol)
: m_symbol(reinterpret_cast<T>(GetProcAddress(t_mod.m_data, t_symbol.c_str())))
{
if (!m_symbol)
{
throw load_module_error(GetErrorMessage(GetLastError()));
}
}
T m_symbol;
};
Loadable_Module(const std::string &t_module_name, const std::string &t_filename) Loadable_Module(const std::string &t_module_name, const std::string &t_filename)
: m_dlmodule(t_filename), m_func(m_dlmodule, "create_chaiscript_module_" + t_module_name)
{
}
ModulePtr get()
{
return m_func.m_symbol();
}
DLModule m_dlmodule;
DLSym<Create_Module_Func> m_func;
};
#else
struct Loadable_Module
{
Loadable_Module(const std::string &, const std::string &)
{ {
throw load_module_error("Loadable module support not available for your platform"); throw load_module_error("Loadable module support not available for your platform");
} }
@@ -87,7 +198,7 @@ namespace chaiscript
throw load_module_error("Loadable module support not available for your platform"); throw load_module_error("Loadable module support not available for your platform");
} }
}; };
#endif
#endif #endif
typedef boost::shared_ptr<Loadable_Module> Loadable_Module_Ptr; typedef boost::shared_ptr<Loadable_Module> Loadable_Module_Ptr;

View File

@@ -210,7 +210,7 @@ namespace chaiscript
try { try {
ss.add_object(node->children[0]->text, Boxed_Value()); ss.add_object(node->children[0]->text, Boxed_Value());
} }
catch (reserved_word_error &rwe) { catch (reserved_word_error &) {
throw Eval_Error("Reserved word used as variable '" + node->children[0]->text + "'", node); throw Eval_Error("Reserved word used as variable '" + node->children[0]->text + "'", node);
} }
return ss.get_object(node->children[0]->text); return ss.get_object(node->children[0]->text);
@@ -708,7 +708,7 @@ namespace chaiscript
param_names, _1), numparams, param_names, _1), numparams,
annotation, guard)), function_name); annotation, guard)), function_name);
} }
catch (reserved_word_error &rwe) { catch (reserved_word_error &) {
throw Eval_Error("Reserved word used as function name '" + function_name + "'", node); throw Eval_Error("Reserved word used as function name '" + function_name + "'", node);
} }
return Boxed_Value(); return Boxed_Value();

View File

@@ -5,6 +5,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chaiscript", "chaiscript.vc
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chai-example", "..\chai-example\chai-example.vcproj", "{CE422E94-B360-4588-8C65-6A9BE80798F9}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chai-example", "..\chai-example\chai-example.vcproj", "{CE422E94-B360-4588-8C65-6A9BE80798F9}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_module", "..\test_module\test_module.vcproj", "{775EDCC2-102F-4E75-A860-9AF398D04145}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@@ -19,6 +21,10 @@ Global
{CE422E94-B360-4588-8C65-6A9BE80798F9}.Debug|Win32.Build.0 = Debug|Win32 {CE422E94-B360-4588-8C65-6A9BE80798F9}.Debug|Win32.Build.0 = Debug|Win32
{CE422E94-B360-4588-8C65-6A9BE80798F9}.Release|Win32.ActiveCfg = Release|Win32 {CE422E94-B360-4588-8C65-6A9BE80798F9}.Release|Win32.ActiveCfg = Release|Win32
{CE422E94-B360-4588-8C65-6A9BE80798F9}.Release|Win32.Build.0 = Release|Win32 {CE422E94-B360-4588-8C65-6A9BE80798F9}.Release|Win32.Build.0 = Release|Win32
{775EDCC2-102F-4E75-A860-9AF398D04145}.Debug|Win32.ActiveCfg = Debug|Win32
{775EDCC2-102F-4E75-A860-9AF398D04145}.Debug|Win32.Build.0 = Debug|Win32
{775EDCC2-102F-4E75-A860-9AF398D04145}.Release|Win32.ActiveCfg = Release|Win32
{775EDCC2-102F-4E75-A860-9AF398D04145}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -49,7 +49,7 @@
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="3" RuntimeLibrary="3"
DisableLanguageExtensions="true" DisableLanguageExtensions="false"
TreatWChar_tAsBuiltInType="false" TreatWChar_tAsBuiltInType="false"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
WarningLevel="4" WarningLevel="4"

View File

@@ -0,0 +1,197 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="test_module"
ProjectGUID="{775EDCC2-102F-4E75-A860-9AF398D04145}"
RootNamespace="test_module"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="..\chaiscript\Boost.vsprops"
UseOfMFC="0"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="C:\Programming\chaiscript\trunk\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TEST_MODULE_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="..\chaiscript\Boost.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TEST_MODULE_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\..\src\test_module.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -7,9 +7,15 @@ std::string hello_world()
return "Hello World"; return "Hello World";
} }
#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
extern "C" extern "C"
{ {
chaiscript::ModulePtr create_chaiscript_module_test() EXPORT chaiscript::ModulePtr create_chaiscript_module_test()
{ {
chaiscript::ModulePtr m(new chaiscript::Module()); chaiscript::ModulePtr m(new chaiscript::Module());