private StubbedModule(string moduleName, NativeInterface @interface, CompilerOptions options = null)
        {
            options = options ?? CompilerOptions.GetDefault();
            if (moduleName.EndsWith(".dll"))
            {
                throw new AzureKinectStubGeneratorException("Module name should not include file extension");
            }

            this.ModuleName      = moduleName;
            this.CompilerOptions = options;
            this.NativeInterface = @interface;

            if (options.TempPath.Exists)
            {
                options.TempPath.Delete(true);
                options.TempPath.Refresh();
            }

            if (options.BinaryPath.Exists)
            {
                options.BinaryPath.Delete(true);
                options.BinaryPath.Refresh();
            }

            options.TempPath.Create();
            options.TempPath.Refresh();
            options.BinaryPath.Create();
            options.BinaryPath.Refresh();

            string executingDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
            string modulePath         = Path.Combine(executingDirectory, moduleName + ".dll");

            GenerateStub(modulePath, @interface, options);
        }
        public static ModuleInfo Analyze(string path, CompilerOptions options = null)
        {
            options = options ?? CompilerOptions.GetDefault();

            List <string> exports = new List <string>();

            if (!File.Exists(path))
            {
                throw new FileNotFoundException("Failed to analyze module, file not found.", path);
            }

            if (!options.TempPath.Exists)
            {
                options.TempPath.Create();
            }

            Regex regex = new Regex(@"^\s+\d+\s+[\dA-Fa-f]+\s+[0-9A-Fa-f]{8}\s+([^\s]*).*?$", System.Text.RegularExpressions.RegexOptions.Multiline);

            // Start the compiler process
            ProcessStartInfo startInfo = new ProcessStartInfo(options.LinkerPath.FullName)
            {
                Arguments              = $"/dump \"{path}\" /exports",
                WorkingDirectory       = options.TempPath.FullName,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                RedirectStandardInput  = true,
            };

            try
            {
                using (Process link = Process.Start(startInfo))
                {
                    string output = link.StandardOutput.ReadToEnd().Replace("\r\n", "\n");

                    link.WaitForExit();

                    if (link.ExitCode != 0)
                    {
                        throw new AzureKinectStubGeneratorException("Link /dump failed");
                    }

                    foreach (Match m in regex.Matches(output))
                    {
                        string functionName = m.Groups[1].Value;

                        exports.Add(functionName);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new AzureKinectStubGeneratorException("Failed to analyze module", ex);
            }

            return(new ModuleInfo(exports.ToArray()));
        }
Пример #3
0
        /// <summary>
        /// Compiles a DLL
        /// </summary>
        /// <param name="sourceFiles">List of source files</param>
        /// <param name="outputBinary">Path of output DLL</param>
        /// <param name="impLib">Path of output import .lib</param>
        /// <param name="options">Compiler Options</param>
        public static void CompileModule(string[] sourceFiles,
                                         string outputBinary,
                                         string impLib,
                                         CompilerOptions options      = null,
                                         string additionalFlags       = null,
                                         string[] additionalLibraries = null,
                                         string[] additionalSources   = null)
        {
            options = options ?? CompilerOptions.GetDefault();
            string moduleName = outputBinary;

            // Set up compiler arguments
            StringBuilder compilerArguments = new StringBuilder();

            compilerArguments.Append(options.CompilerFlags);
            if (additionalFlags != null)
            {
                compilerArguments.Append(" ");
                compilerArguments.Append(additionalFlags);
            }
            compilerArguments.Append(" /nologo");
            compilerArguments.Append(" /LD"); // Create a .DLL

            foreach (string sourceFilePath in sourceFiles)
            {
                compilerArguments.Append($" \"{sourceFilePath}\"");
            }
            if (additionalSources != null)
            {
                foreach (string sourceFilePath in additionalSources)
                {
                    compilerArguments.Append($" \"{sourceFilePath}\"");
                }
            }
            foreach (DirectoryInfo includePath in options.IncludePaths)
            {
                compilerArguments.Append($" \"/I{includePath.FullName.TrimEnd('\\')}\"");
            }

            // Linker options
            compilerArguments.Append(" /link");
            foreach (DirectoryInfo libraryPath in options.LibraryPaths)
            {
                compilerArguments.Append($" \"/LIBPATH:{libraryPath.FullName.TrimEnd('\\')}\"");
            }

            compilerArguments.Append($" \"/OUT:{moduleName}\"");
            if (impLib != null)
            {
                compilerArguments.Append($" \"/IMPLIB:{impLib}\"");
            }
            foreach (string library in options.Libraries)
            {
                compilerArguments.Append(" " + library);
            }
            if (additionalLibraries != null)
            {
                foreach (string library in additionalLibraries)
                {
                    compilerArguments.Append(" " + library);
                }
            }

            // Start the compiler process
            ProcessStartInfo startInfo = new ProcessStartInfo(options.CompilerPath.FullName)
            {
                Arguments              = compilerArguments.ToString(),
                WorkingDirectory       = options.TempPath.FullName,
                RedirectStandardOutput = true
            };

            Debug.WriteLine(startInfo.Arguments);
            try
            {
                using (Process cl = Process.Start(startInfo))
                {
                    string output = cl.StandardOutput.ReadToEnd().Replace("\r\n", "\n");

                    cl.WaitForExit();

                    if (cl.ExitCode != 0)
                    {
                        throw new AzureKinectStubGeneratorException("Compilation failed: " + output);
                    }
                }
            }
            catch (System.ComponentModel.Win32Exception ex)
            {
                if ((uint)ex.ErrorCode == 0x80004005)
                {
                    throw new AzureKinectStubGeneratorException($"Could not find compiler \"{options.CompilerPath}\". Ensure you are running in a developer environment.", ex);
                }
                else
                {
                    throw;
                }
            }
        }