开发者

Getting error " Attempted to read or write protected memory"

This is what is in the header file.

/// Creates a new file geodatabase in the specified location.
/// @param[in]    path The location where the geodatabase should be created.
/// @param[out]   geodatabase A reference to the newly-created geodatabase.
/// @return       A long integer indicating whether the method finished successfully.
EXT_FILEGDB_API long CreateGeodatabase(const std::wstring& pat开发者_开发知识库h, Geodatabase& geodatabase);

This is what my dllimport looks like.

[DllImport("FileGDBAPI.dll", EntryPoint = "#49", SetLastError=true, CallingConvention=CallingConvention.Winapi)]
        public static extern int CreateGeodatabase([MarshalAs(UnmanagedType.LPStr)]string path, ref IntPtr geodatabase);

..and this is the code thats using it.

IntPtr Geodatabase = IntPtr.Zero;
                FileGDBAPI_wrapper.CreateGeodatabase("c:\temp\testGDB.gdb", ref Geodatabase);

What am I doing wrong?


I see two possible problems:

  1. The C++ code is using a wide string, the C# code an ANSI string
  2. The C++ code is using the std::wstring class, and not a c style null terminated string

I don't think you can fix the second problem easily without changing the API on the C++ side


If you are using .NET 4.0, try passing parameters without the ref keyword.

i.e.

FileGDBAPI_wrapper.CreateGeodatabase("c:\temp\testGDB.gdb", /ref/ Geodatabase);

and let me know if this works for you.

EDIT

Forget about my previous answer, I was typically ignorant.

I think you need to mark the Geodatabase as out instead of ref in both the declaration and invocation of the function; in this case you will NOT need to initialize your IntPtr before passing it to CreateGeodatabase()

I guess -and may be I am still ignorant - the problem related to declaring the Geodatabase argument in your library as a reference not as a pointer, that is, you can't pass null (IntPtr.Zero) to it, and typically, you don't need so, you need it as an out parameter.


maybe this is useful

void MarshalString ( String ^ s, wstring& os ) {
            using namespace Runtime::InteropServices;
            const wchar_t* chars = 
                (const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
            os = chars;
            Marshal::FreeHGlobal(IntPtr((void*)chars));
        }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜