Самый простой способ переместить массив от C++ до C#, измените его и пасуйте назад его к C++

Проблема в том, что пакет google_maps_flutter требует разрешения для доступа к вашему местоположению, но в пакете нет собственных кодов для запроса этого разрешения.

Так что вам нужно написать собственный код или просто установить другой пакет, который может получить это разрешение.

Установите это: https://pub.dartlang.org/packages/location

Затем:

getLocationPermission() async {
    final Location location = new Location();
    try {
      location.requestPermission(); //to lunch location permission popup
    } on PlatformException catch (e) {
      if (e.code == 'PERMISSION_DENIED') {
        print('Permission denied');
      }
    }
  }

Или, если вы хотите более твердый код, это мой код для какого-то проекта (с пакетом местоположения):

//Show some loading indicator depends on this boolean variable
bool askingPermission = false;

@override
  void initState() {
    this.getLocationPermission();
    super.initState();
  }

  Future getLocationPermission() async {
    setState(() {
      this.askingPermission = true;
    });
    bool result;
    final Location location = Location();
    try {
      if (await location.hasPermission())
        result = true;
      else {
        result = await location.requestPermission();
      }
      print('getLocationPermission: '
          '${result ? 'Access Allowed' : 'Access Denied'}');
    } catch (log, trace) {
      result = false;
      print('getLocationPermission/log: $log');
      print('getLocationPermission/trace: $trace');
    } finally {
      setState(() {
        this.askingPermission = false;
      });
    }
    return result;
  }

6
задан Alex 22 February 2009 в 18:52
поделиться

3 ответа

Я экспериментировал с этим только что, но к сожалению забыл, как все это совместилось... для моей цели, это оказалось горестно медленным, таким образом, я отключил C# и вернулся ко всему C++. Когда Вы говорите, что Вы - прежде всего, разработчик C#, я надеюсь, что Вы понимаете указатели, потому что, если Вы не делаете, нет никакого способа быть нежным.

Передача массивов в основном свелась к использованию семейства CoTaskMemAlloc функций на стороне C++ (http://msdn.microsoft.com/en-us/library/ms692727 (По сравнению с 85) .aspx) и класс Маршала на стороне C# (http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx - который имеет методы как AllocCoTaskMem). Для C# я закончил со служебным классом:

public class serviceUtils
{
    unsafe public long stringToCoTaskPtr( ref str thestring )
    {
        return (long)Marshal.StringToCoTaskMemAnsi(thestring.theString).ToPointer();//TODO : what errors occur from here? handle them
    }

    unsafe public long bytesToCoTaskPtr( ref bytes thebytes, ref short byteCnt)
    {
        byteCnt = (short)thebytes.theArray.Length;
        IntPtr tmpptr = new IntPtr();
        tmpptr = Marshal.AllocCoTaskMem(byteCnt);
        Marshal.Copy(thebytes.theArray, 0, tmpptr, byteCnt);
        return (long)tmpptr.ToPointer();
    }

    public void freeCoTaskMemPtr(long ptr)
    {
        Marshal.FreeCoTaskMem(new IntPtr(ptr));//TODO : errors from here?
    }

    public string coTaskPtrToString(long theptr)
    {
        return Marshal.PtrToStringAnsi(new IntPtr(theptr));
    }

    public byte[] coTaskPtrToBytes(long theptr, short thelen)
    {
        byte[] tmpbytes = new byte[thelen];
        Marshal.Copy(new IntPtr(theptr), tmpbytes, 0, thelen);
        return tmpbytes;
    }
}

Только бросить еще некоторый код в Вас: этот C++

#import "..\COMClient\bin\Debug\COMClient.tlb" named_guids raw_interfaces_only
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);   //Initialize all COM Components
COMClient::IComCalculatorPtr pCalc;
// CreateInstance parameters
HRESULT hRes = pCalc.CreateInstance(COMClient::CLSID_ComCalculator);
if (hRes == S_OK) {
    long size = 5;
    LPVOID ptr = CoTaskMemAlloc( size );
    if( ptr != NULL )
    {
        memcpy( ptr, "12345", size );
        short ans = 0;
        pCalc->changeBytes( (__int64*)&ptr, &size, &ans );
        CoTaskMemFree(ptr);
    }
}

CoUninitialize ();   //DeInitialize all COM Components

return 0;
}

названный этим c#

    public short changeBytes(ref long ptr, ref int arraysize)
    {
        try
        {
            IntPtr interopPtr = new IntPtr(ptr);                
            testservice.ByteArray bytes = new testservice.ByteArray();
            byte[] somebytes = new byte[arraysize];
            Marshal.Copy(interopPtr, somebytes, 0, arraysize);
            bytes.theArray = somebytes;

            CalculatorClient client = generateClient();
            client.takeArray(ref bytes);
            client.Close();
            if (arraysize < bytes.theArray.Length)
            {
                interopPtr = Marshal.ReAllocCoTaskMem(interopPtr, bytes.theArray.Length);//TODO : throws an exception if fails... deal with it
            }
            Marshal.Copy(bytes.theArray, 0, interopPtr, bytes.theArray.Length);
            ptr = interopPtr.ToInt64();

            arraysize = bytes.theArray.Length;

            //TODO : do we need to free IntPtr? check all code for memory leaks... check for successful allocation
        }
        catch(Exception e)
        {
            return 3;
        }

        return 2;
    }

Извините, но у меня нет времени, чтобы разработать все это и объяснить это правильно, надо надеяться, это даст Вам подсказки в правильном направлении, по крайней мере некоторые вещи погуглить.Удачи

PS: Я заставил всю информацию писать этот материал от сети, таким образом, это там.

3
ответ дан 17 December 2019 в 07:09
поделиться

Я думаю, что могу использовать C ++\CLI DLL для внешнего приложения поэтому, если это будет легче, чем прямой COM затем, то я буду готов посмотреть на это.

Если у Вас не будет большого опыта COM (и массивы значительно не просты в COM), затем, то C++ / обертка CLI вокруг третьей стороны, вероятно, будет легче.

Это также только включит единственный этап маршалинга (собственный компонент <-> управляемый), а не дополнительный шаг необходимая Обертка для COM-вызовов, в которой Вы будете нуждаться для управляемого <-> COM, взаимодействующий через интерфейс).

1
ответ дан 17 December 2019 в 07:09
поделиться

Это тоже сработает?

В C # 1. Позвоните в Marshal.PtrToStructure. 2. Измените значение 3. Позвоните в Marshal.StructureToPtr

.
0
ответ дан 17 December 2019 в 07:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: