public static CompiledEffect FromString(
     UnmanagedLibrary dx9Handle,
     string source,
     CompilerOptions options)
 {
     return(new CompiledEffect(
                dx9Handle,
                source,
                options));
 }
        CompiledEffect(
            UnmanagedLibrary dx9Handle,
            string source,
            CompilerOptions options)
        {
            m_dx9Handle = dx9Handle;
            m_d3DXCreateEffectCompiler = m_dx9Handle
                                         .GetUnmanagedFunction <D3DXCreateEffectCompilerProc>(
                EffectCompilerFuncName);

            SourceCode       = source;
            CompileFlags     = options;
            CompileSucceeded = false;


            var errorbuf = default(ID3DXBuffer);
            var compiler = default(ID3DXEffectCompiler);

            try
            {
                var len = Encoding.ASCII.GetByteCount(SourceCode);

                var hr = m_d3DXCreateEffectCompiler(
                    SourceCode,
                    (uint)len,
                    null,
                    IntPtr.Zero,
                    options.ToD3DXSHADER(),
                    out compiler,
                    out errorbuf);
                ErrorMessage = errorbuf != null
                              ? errorbuf.AsAnsiString()
                              : string.Empty;

                if (!D3DXUtil.Succeeded(hr))
                {
                    return;
                }

                CompileSucceeded = true;

                var maybeEffectDesc = compiler.GetDesc();
                if (!maybeEffectDesc.HasValue)
                {
                    return;
                }

                var effectDesc       = maybeEffectDesc.Value;
                var dxEffectCompiler = compiler;
                var functions        = from funcIndex in Enumerable.Range(
                    0,
                    (int)effectDesc.Functions)
                                       let funcHandle =
                    dxEffectCompiler.GetFunction((uint)funcIndex)
                    let funcDesc =
                        dxEffectCompiler.GetFunctionDesc(funcHandle)
                        // funcDesc.Annotations are always empty, so we ignore them
                        select
                        funcDesc.HasValue
                                  ? funcDesc.Value.Name.ReadAsAnsiString()
                                  : string.Empty;

                var effectCompiler = compiler;

                var topLevelParams =
                    from paramIndex in Enumerable.Range(
                        0,
                        (int)effectDesc.Parameters)
                    select effectCompiler.GetParameter(
                        IntPtr.Zero,
                        paramIndex);

                Creator            = effectDesc.Creator.ReadAsAnsiString();
                Functions          = functions.ToArray();
                TopLevelParameters = topLevelParams.ToArray();

                return;
            }
            finally
            {
                if (errorbuf != null)
                {
                    Marshal.ReleaseComObject(errorbuf);
                }
                if (compiler != null)
                {
                    Marshal.ReleaseComObject(compiler);
                }
            }
        }