I have a dll that exports not only functions, but also values. The dll I'm interested in is from the R Project (http://www.r-project.org/),开发者_开发百科 it's in the R.dll that contains the r language runtime. The declaration in the header file is:
LibExtern SEXP R_GlobalEnv;
And when when I run dumpbin /exports I can see:
194 C1 00326C08 R_GlobalEnv
But I can't seem to find any examples of how to bind such a value from C# or F#. Can anyone enlightenment me to how I might get a reference to it?
I don't known if there is a way directly from C# or F#. But I think that a C++/CLI wrapper should work.
After Nick pointed me in the direction of R.NET I was able to look and see how they solved this problem.
First they use the win32 api to load the library (or equivalent on other platforms):
#if MAC || LINUX
private static IntPtr LoadLibrary(string filename)
{
const int RTLD_LAZY = 0x1;
if (filename.StartsWith("/"))
{
return dlopen(filename, RTLD_LAZY);
}
string[] searchPaths = (System.Environment.GetEnvironmentVariable(LibraryPath, EnvironmentVariableTarget.Process) ?? "").Split(Path.PathSeparator);
foreach (string directory in searchPaths)
{
string path = Path.Combine(directory, filename);
if (File.Exists(path))
{
return dlopen(path, RTLD_LAZY);
}
}
return IntPtr.Zero;
}
[DllImport(DynamicLoadingLibraryName)]
private static extern IntPtr dlopen([MarshalAs(UnmanagedType.LPStr)] string filename, int flag);
#elif WINDOWS
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
Then they use get GetProcAddress function from kernel32.dll (or equivalent on other platforms) to get the actual address of the variable:
#if MAC
[DllImport("libdl.dylib", EntryPoint = "dlsym")]
#elif LINUX
[DllImport("libdl.so", EntryPoint = "dlsym")]
#elif WINDOWS
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
#endif
private static extern IntPtr GetSymbolPointer(IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] string symbol);
精彩评论